home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / cpuintrf.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  99KB  |  3,133 lines

  1. /***************************************************************************
  2.  
  3.   cpuintrf.c
  4.  
  5.   Don't you love MS-DOS 8+3 names? That stands for CPU interface.
  6.   Functions needed to interface the CPU emulator with the other parts of
  7.   the emulation.
  8.  
  9. ***************************************************************************/
  10.  
  11. #include <signal.h>
  12. #include "driver.h"
  13. #include "timer.h"
  14. #include "state.h"
  15. #include "mamedbg.h"
  16. #include "hiscore.h"
  17.  
  18. #if (HAS_Z80)
  19. #include "cpu/z80/z80.h"
  20. #endif
  21. #if (HAS_Z80GB)
  22. #include "cpu/z80gb/z80gb.h"
  23. #endif
  24. #if (HAS_8080 || HAS_8085A)
  25. #include "cpu/i8085/i8085.h"
  26. #endif
  27. #if (HAS_M6502 || HAS_M65C02 || HAS_M65SC02 || HAS_M6510 || HAS_M6510T || HAS_M7501 || HAS_M8502 || HAS_N2A03)
  28. #include "cpu/m6502/m6502.h"
  29. #endif
  30. #if (HAS_M4510)
  31. #include "cpu/m6502/m4510.h"
  32. #endif
  33. #if (HAS_M65CE02)
  34. #include "cpu/m6502/m65ce02.h"
  35. #endif
  36. #if (HAS_M6509)
  37. #include "cpu/m6502/m6509.h"
  38. #endif
  39. #if (HAS_H6280)
  40. #include "cpu/h6280/h6280.h"
  41. #endif
  42. #if (HAS_I86)
  43. #include "cpu/i86/i86intf.h"
  44. #endif
  45. #if (HAS_I88)
  46. #include "cpu/i86/i88intf.h"
  47. #endif
  48. #if (HAS_I186)
  49. #include "cpu/i86/i186intf.h"
  50. #endif
  51. #if (HAS_I188)
  52. #include "cpu/i86/i188intf.h"
  53. #endif
  54. #if (HAS_I286)
  55. #include "cpu/i86/i286intf.h"
  56. #endif
  57. #if (HAS_V20 || HAS_V30 || HAS_V33)
  58. #include "cpu/nec/necintrf.h"
  59. #endif
  60. #if (HAS_I8035 || HAS_I8039 || HAS_I8048 || HAS_N7751)
  61. #include "cpu/i8039/i8039.h"
  62. #endif
  63. #if (HAS_M6800 || HAS_M6801 || HAS_M6802 || HAS_M6803 || HAS_M6808 || HAS_HD63701)
  64. #include "cpu/m6800/m6800.h"
  65. #endif
  66. #if (HAS_M6805 || HAS_M68705 || HAS_HD63705)
  67. #include "cpu/m6805/m6805.h"
  68. #endif
  69. #if (HAS_HD6309 || HAS_M6809)
  70. #include "cpu/m6809/m6809.h"
  71. #endif
  72. #if (HAS_KONAMI)
  73. #include "cpu/konami/konami.h"
  74. #endif
  75. #if (HAS_M68000 || defined HAS_M68010 || HAS_M68020 || HAS_M68EC020)
  76. #include "cpu/m68000/m68000.h"
  77. #endif
  78. #if (HAS_T11)
  79. #include "cpu/t11/t11.h"
  80. #endif
  81. #if (HAS_S2650)
  82. #include "cpu/s2650/s2650.h"
  83. #endif
  84. #if (HAS_TMS34010)
  85. #include "cpu/tms34010/tms34010.h"
  86. #endif
  87. #if (HAS_TMS9900) || (HAS_TMS9940) || (HAS_TMS9980) || (HAS_TMS9985) \
  88.     || (HAS_TMS9989) || (HAS_TMS9995) || (HAS_TMS99105A) || (HAS_TMS99110A)
  89. #include "cpu/tms9900/tms9900.h"
  90. #endif
  91. #if (HAS_Z8000)
  92. #include "cpu/z8000/z8000.h"
  93. #endif
  94. #if (HAS_TMS320C10)
  95. #include "cpu/tms32010/tms32010.h"
  96. #endif
  97. #if (HAS_CCPU)
  98. #include "cpu/ccpu/ccpu.h"
  99. #endif
  100. #if (HAS_PDP1)
  101. #include "cpu/pdp1/pdp1.h"
  102. #endif
  103. #if (HAS_ADSP2100)
  104. #include "cpu/adsp2100/adsp2100.h"
  105. #endif
  106. #if (HAS_MIPS)
  107. #include "cpu/mips/mips.h"
  108. #endif
  109.  
  110. /* these are triggers sent to the timer system for various interrupt events */
  111. #define TRIGGER_TIMESLICE        -1000
  112. #define TRIGGER_INT             -2000
  113. #define TRIGGER_YIELDTIME        -3000
  114. #define TRIGGER_SUSPENDTIME     -4000
  115.  
  116. #define VERBOSE 0
  117.  
  118. #define SAVE_STATE_TEST 0
  119. #if VERBOSE
  120. #define LOG(x)    logerror x
  121. #else
  122. #define LOG(x)
  123. #endif
  124.  
  125. #define CPUINFO_SIZE    (5*sizeof(int)+4*sizeof(void*)+2*sizeof(double))
  126. /* How do I calculate the next power of two from CPUINFO_SIZE using a macro? */
  127. #ifdef __LP64__
  128. #define CPUINFO_ALIGN    (128-CPUINFO_SIZE)
  129. #else
  130. #define CPUINFO_ALIGN    (64-CPUINFO_SIZE)
  131. #endif
  132.  
  133. struct cpuinfo
  134. {
  135.     struct cpu_interface *intf;     /* pointer to the interface functions */
  136.     int iloops;                     /* number of interrupts remaining this frame */
  137.     int totalcycles;                /* total CPU cycles executed */
  138.     int vblankint_countdown;        /* number of vblank callbacks left until we interrupt */
  139.     int vblankint_multiplier;        /* number of vblank callbacks per interrupt */
  140.     void *vblankint_timer;            /* reference to elapsed time counter */
  141.     double vblankint_period;        /* timing period of the VBLANK interrupt */
  142.     void *timedint_timer;            /* reference to this CPU's timer */
  143.     double timedint_period;         /* timing period of the timed interrupt */
  144.     void *context;                    /* dynamically allocated context buffer */
  145.     int save_context;                /* need to context switch this CPU? yes or no */
  146.     UINT8 filler[CPUINFO_ALIGN];    /* make the array aligned to next power of 2 */
  147. };
  148.  
  149. static struct cpuinfo cpu[MAX_CPU];
  150.  
  151. static int activecpu,totalcpu;
  152. static int cycles_running;    /* number of cycles that the CPU emulation was requested to run */
  153.                     /* (needed by cpu_getfcount) */
  154. static int have_to_reset;
  155.  
  156. static int interrupt_enable[MAX_CPU];
  157. static int interrupt_vector[MAX_CPU];
  158.  
  159. static int irq_line_state[MAX_CPU * MAX_IRQ_LINES];
  160. static int irq_line_vector[MAX_CPU * MAX_IRQ_LINES];
  161.  
  162. static int watchdog_counter;
  163.  
  164. static void *vblank_timer;
  165. static int vblank_countdown;
  166. static int vblank_multiplier;
  167. static double vblank_period;
  168.  
  169. static void *refresh_timer;
  170. static double refresh_period;
  171. static double refresh_period_inv;
  172.  
  173. static void *timeslice_timer;
  174. static double timeslice_period;
  175.  
  176. static double scanline_period;
  177. static double scanline_period_inv;
  178.  
  179. static int usres; /* removed from cpu_run and made global */
  180. static int vblank;
  181. static int current_frame;
  182.  
  183. static void cpu_generate_interrupt(int cpunum, int (*func)(void), int num);
  184. static void cpu_vblankintcallback(int param);
  185. static void cpu_timedintcallback(int param);
  186. static void cpu_internal_interrupt(int cpunum, int type);
  187. static void cpu_manualnmicallback(int param);
  188. static void cpu_manualirqcallback(int param);
  189. static void cpu_internalintcallback(int param);
  190. static void cpu_manualintcallback(int param);
  191. static void cpu_clearintcallback(int param);
  192. static void cpu_resetcallback(int param);
  193. static void cpu_haltcallback(int param);
  194. static void cpu_timeslicecallback(int param);
  195. static void cpu_vblankreset(void);
  196. static void cpu_vblankcallback(int param);
  197. static void cpu_updatecallback(int param);
  198. static double cpu_computerate(int value);
  199. static void cpu_inittimers(void);
  200.  
  201.  
  202. /* default irq callback handlers */
  203. static int cpu_0_irq_callback(int irqline);
  204. static int cpu_1_irq_callback(int irqline);
  205. static int cpu_2_irq_callback(int irqline);
  206. static int cpu_3_irq_callback(int irqline);
  207.  
  208. /* and a list of them for indexed access */
  209. static int (*cpu_irq_callbacks[MAX_CPU])(int) = {
  210.     cpu_0_irq_callback,
  211.     cpu_1_irq_callback,
  212.     cpu_2_irq_callback,
  213.     cpu_3_irq_callback
  214. };
  215.  
  216. /* Default window layout for the debugger */
  217. UINT8 default_win_layout[] = {
  218.      0, 0,80, 5,    /* register window (top rows) */
  219.      0, 5,24,17,    /* disassembler window (left, middle columns) */
  220.     25, 5,55, 8,    /* memory #1 window (right, upper middle) */
  221.     25,14,55, 8,    /* memory #2 window (right, lower middle) */
  222.      0,23,80, 1     /* command line window (bottom row) */
  223. };
  224.  
  225. /* Dummy interfaces for non-CPUs */
  226. static void Dummy_reset(void *param);
  227. static void Dummy_exit(void);
  228. static int Dummy_execute(int cycles);
  229. static void Dummy_burn(int cycles);
  230. static unsigned Dummy_get_context(void *regs);
  231. static void Dummy_set_context(void *regs);
  232. static unsigned Dummy_get_pc(void);
  233. static void Dummy_set_pc(unsigned val);
  234. static unsigned Dummy_get_sp(void);
  235. static void Dummy_set_sp(unsigned val);
  236. static unsigned Dummy_get_reg(int regnum);
  237. static void Dummy_set_reg(int regnum, unsigned val);
  238. static void Dummy_set_nmi_line(int state);
  239. static void Dummy_set_irq_line(int irqline, int state);
  240. static void Dummy_set_irq_callback(int (*callback)(int irqline));
  241. static int Dummy_ICount;
  242. static const char *Dummy_info(void *context, int regnum);
  243. static unsigned Dummy_dasm(char *buffer, unsigned pc);
  244.  
  245. /* Convenience macros - not in cpuintrf.h because they shouldn't be used by everyone */
  246. #define RESET(index)                    ((*cpu[index].intf->reset)(Machine->drv->cpu[index].reset_param))
  247. #define EXECUTE(index,cycles)            ((*cpu[index].intf->execute)(cycles))
  248. #define GETCONTEXT(index,context)        ((*cpu[index].intf->get_context)(context))
  249. #define SETCONTEXT(index,context)        ((*cpu[index].intf->set_context)(context))
  250. #define GETPC(index)                    ((*cpu[index].intf->get_pc)())
  251. #define SETPC(index,val)                ((*cpu[index].intf->set_pc)(val))
  252. #define GETSP(index)                    ((*cpu[index].intf->get_sp)())
  253. #define SETSP(index,val)                ((*cpu[index].intf->set_sp)(val))
  254. #define GETREG(index,regnum)            ((*cpu[index].intf->get_reg)(regnum))
  255. #define SETREG(index,regnum,value)        ((*cpu[index].intf->set_reg)(regnum,value))
  256. #define SETNMILINE(index,state)         ((*cpu[index].intf->set_nmi_line)(state))
  257. #define SETIRQLINE(index,line,state)    ((*cpu[index].intf->set_irq_line)(line,state))
  258. #define SETIRQCALLBACK(index,callback)    ((*cpu[index].intf->set_irq_callback)(callback))
  259. #define INTERNAL_INTERRUPT(index,type)    if( cpu[index].intf->internal_interrupt ) ((*cpu[index].intf->internal_interrupt)(type))
  260. #define CPUINFO(index,context,regnum)    ((*cpu[index].intf->cpu_info)(context,regnum))
  261. #define CPUDASM(index,buffer,pc)        ((*cpu[index].intf->cpu_dasm)(buffer,pc))
  262. #define ICOUNT(index)                    (*cpu[index].intf->icount)
  263. #define INT_TYPE_NONE(index)            (cpu[index].intf->no_int)
  264. #define INT_TYPE_IRQ(index)             (cpu[index].intf->irq_int)
  265. #define INT_TYPE_NMI(index)             (cpu[index].intf->nmi_int)
  266. #define READMEM(index,offset)            ((*cpu[index].intf->memory_read)(offset))
  267. #define WRITEMEM(index,offset,data)     ((*cpu[index].intf->memory_write)(offset,data))
  268. #define SET_OP_BASE(index,pc)            ((*cpu[index].intf->set_op_base)(pc))
  269.  
  270. #define CPU_TYPE(index)                 (Machine->drv->cpu[index].cpu_type & ~CPU_FLAGS_MASK)
  271. #define CPU_AUDIO(index)                (Machine->drv->cpu[index].cpu_type & CPU_AUDIO_CPU)
  272.  
  273. #define IFC_INFO(cpu,context,regnum)    ((cpuintf[cpu].cpu_info)(context,regnum))
  274.  
  275. /* most CPUs use this macro */
  276. #define CPU0(cpu,name,nirq,dirq,oc,i0,i1,i2,mem,shift,bits,endian,align,maxinst,MEM) \
  277.     {                                                                               \
  278.         CPU_##cpu,                                                                   \
  279.         name##_reset, name##_exit, name##_execute, NULL,                           \
  280.         name##_get_context, name##_set_context, name##_get_pc, name##_set_pc,       \
  281.         name##_get_sp, name##_set_sp, name##_get_reg, name##_set_reg,               \
  282.         name##_set_nmi_line, name##_set_irq_line, name##_set_irq_callback,           \
  283.         NULL,NULL,NULL, name##_info, name##_dasm,                                   \
  284.         nirq, dirq, &##name##_ICount, oc, i0, i1, i2,                               \
  285.         cpu_readmem##mem, cpu_writemem##mem, cpu_setOPbase##mem,                   \
  286.         shift, bits, CPU_IS_##endian, align, maxinst,                               \
  287.         ABITS1_##MEM, ABITS2_##MEM, ABITS_MIN_##MEM                                \
  288.     }
  289.  
  290. /* CPUs which have _burn, _state_save and _state_load functions */
  291. #define CPU1(cpu,name,nirq,dirq,oc,i0,i1,i2,mem,shift,bits,endian,align,maxinst,MEM)   \
  292.     {                                                                               \
  293.         CPU_##cpu,                                                                   \
  294.         name##_reset, name##_exit, name##_execute,                                   \
  295.         name##_burn,                                                               \
  296.         name##_get_context, name##_set_context, name##_get_pc, name##_set_pc,       \
  297.         name##_get_sp, name##_set_sp, name##_get_reg, name##_set_reg,               \
  298.         name##_set_nmi_line, name##_set_irq_line, name##_set_irq_callback,           \
  299.         NULL,name##_state_save,name##_state_load, name##_info, name##_dasm,        \
  300.         nirq, dirq, &##name##_ICount, oc, i0, i1, i2,                               \
  301.         cpu_readmem##mem, cpu_writemem##mem, cpu_setOPbase##mem,                   \
  302.         shift, bits, CPU_IS_##endian, align, maxinst,                               \
  303.         ABITS1_##MEM, ABITS2_##MEM, ABITS_MIN_##MEM                                \
  304.     }
  305.  
  306. /* CPUs which have the _internal_interrupt function */
  307. #define CPU2(cpu,name,nirq,dirq,oc,i0,i1,i2,mem,shift,bits,endian,align,maxinst,MEM)   \
  308.     {                                                                               \
  309.         CPU_##cpu,                                                                   \
  310.         name##_reset, name##_exit, name##_execute,                                   \
  311.         NULL,                                                                       \
  312.         name##_get_context, name##_set_context, name##_get_pc, name##_set_pc,       \
  313.         name##_get_sp, name##_set_sp, name##_get_reg, name##_set_reg,               \
  314.         name##_set_nmi_line, name##_set_irq_line, name##_set_irq_callback,           \
  315.         name##_internal_interrupt,NULL,NULL, name##_info, name##_dasm,               \
  316.         nirq, dirq, &##name##_ICount, oc, i0, i1, i2,                               \
  317.         cpu_readmem##mem, cpu_writemem##mem, cpu_setOPbase##mem,                   \
  318.         shift, bits, CPU_IS_##endian, align, maxinst,                               \
  319.         ABITS1_##MEM, ABITS2_##MEM, ABITS_MIN_##MEM                                \
  320.     }                                                                               \
  321.  
  322.  
  323.  
  324. /* warning the ordering must match the one of the enum in driver.h! */
  325. struct cpu_interface cpuintf[] =
  326. {
  327.     CPU0(DUMMY,    Dummy,     1,  0,1.00,0,                   -1,               -1,               16,      0,16,LE,1, 1,16    ),
  328. #if (HAS_Z80)
  329.     CPU1(Z80,       z80,      1,255,1.00,Z80_IGNORE_INT,    Z80_IRQ_INT,    Z80_NMI_INT,    16,      0,16,LE,1, 4,16    ),
  330. #endif
  331. #if (HAS_Z80GB)
  332.     CPU0(Z80GB,    z80gb,     5,255,1.00,Z80GB_IGNORE_INT,  0,               1,               16,      0,16,LE,1, 4,16    ),
  333. #endif
  334. #if (HAS_8080)
  335.     CPU0(8080,       i8080,     4,255,1.00,I8080_NONE,        I8080_INTR,       I8080_TRAP,       16,      0,16,LE,1, 3,16    ),
  336. #endif
  337. #if (HAS_8085A)
  338.     CPU0(8085A,    i8085,     4,255,1.00,I8085_NONE,        I8085_INTR,       I8085_TRAP,       16,      0,16,LE,1, 3,16    ),
  339. #endif
  340. #if (HAS_M6502)
  341.     CPU0(M6502,    m6502,     1,  0,1.00,M6502_INT_NONE,    M6502_INT_IRQ,  M6502_INT_NMI,  16,      0,16,LE,1, 3,16    ),
  342. #endif
  343. #if (HAS_M65C02)
  344.     CPU0(M65C02,   m65c02,     1,  0,1.00,M65C02_INT_NONE,   M65C02_INT_IRQ, M65C02_INT_NMI, 16,      0,16,LE,1, 3,16    ),
  345. #endif
  346. #if (HAS_M65SC02)
  347.     CPU0(M65SC02,  m65sc02,  1,  0,1.00,M65SC02_INT_NONE,  M65SC02_INT_IRQ,M65SC02_INT_NMI,16,      0,16,LE,1, 3,16    ),
  348. #endif
  349. #if (HAS_M65CE02)
  350.     CPU0(M65CE02,  m65ce02,  1,  0,1.00,M65CE02_INT_NONE,  M65CE02_INT_IRQ,M65CE02_INT_NMI,16,      0,16,LE,1, 3,16    ),
  351. #endif
  352. #if (HAS_M6509)
  353.     CPU0(M6509,    m6509,     1,  0,1.00,M6509_INT_NONE,    M6509_INT_IRQ,  M6509_INT_NMI,  20,      0,20,LE,1, 3,20    ),
  354. #endif
  355. #if (HAS_M6510)
  356.     CPU0(M6510,    m6510,     1,  0,1.00,M6510_INT_NONE,    M6510_INT_IRQ,  M6510_INT_NMI,  16,      0,16,LE,1, 3,16    ),
  357. #endif
  358. #if (HAS_M6510T)
  359.     CPU0(M6510T,   m6510t,     1,  0,1.00,M6510T_INT_NONE,   M6510T_INT_IRQ, M6510T_INT_NMI, 16,      0,16,LE,1, 3,16    ),
  360. #endif
  361. #if (HAS_M7501)
  362.     CPU0(M7501,    m7501,     1,  0,1.00,M7501_INT_NONE,    M7501_INT_IRQ,  M7501_INT_NMI,  16,      0,16,LE,1, 3,16    ),
  363. #endif
  364. #if (HAS_M8502)
  365.     CPU0(M8502,    m8502,     1,  0,1.00,M8502_INT_NONE,    M8502_INT_IRQ,  M8502_INT_NMI,  16,      0,16,LE,1, 3,16    ),
  366. #endif
  367. #if (HAS_N2A03)
  368.     CPU0(N2A03,    n2a03,     1,  0,1.00,N2A03_INT_NONE,    N2A03_INT_IRQ,  N2A03_INT_NMI,  16,      0,16,LE,1, 3,16    ),
  369. #endif
  370. #if (HAS_M4510)
  371.     CPU0(M4510,    m4510,     1,  0,1.00,M4510_INT_NONE,    M4510_INT_IRQ,  M4510_INT_NMI,  20,      0,20,LE,1, 3,20    ),
  372. #endif
  373. #if (HAS_H6280)
  374.     CPU0(H6280,    h6280,     3,  0,1.00,H6280_INT_NONE,    -1,               H6280_INT_NMI,  21,      0,21,LE,1, 3,21    ),
  375. #endif
  376. #if (HAS_I86)
  377.     CPU0(I86,       i86,      1,  0,1.00,I86_INT_NONE,       -1000,           I86_NMI_INT,    20,      0,20,LE,1, 5,20    ),
  378. #endif
  379. #if (HAS_I88)
  380.     CPU0(I88,       i88,      1,  0,1.00,I88_INT_NONE,       -1000,           I88_NMI_INT,    20,      0,20,LE,1, 5,20    ),
  381. #endif
  382. #if (HAS_I186)
  383.     CPU0(I186,       i186,     1,  0,1.00,I186_INT_NONE,       -1000,           I186_NMI_INT,   20,      0,20,LE,1, 5,20    ),
  384. #endif
  385. #if (HAS_I188)
  386.     CPU0(I188,       i188,     1,  0,1.00,I188_INT_NONE,       -1000,           I188_NMI_INT,   20,      0,20,LE,1, 5,20    ),
  387. #endif
  388. #if (HAS_I286)
  389.     CPU0(I286,       i286,     1,  0,1.00,I286_INT_NONE,       -1000,           I286_NMI_INT,   24,      0,24,LE,1, 5,24    ),
  390. #endif
  391. #if (HAS_V20)
  392.     CPU0(V20,       v20,      1,  0,1.00,NEC_INT_NONE,       -1000,           NEC_NMI_INT,    20,      0,20,LE,1, 5,20    ),
  393. #endif
  394. #if (HAS_V30)
  395.     CPU0(V30,       v30,      1,  0,1.00,NEC_INT_NONE,       -1000,           NEC_NMI_INT,    20,      0,20,LE,1, 5,20    ),
  396. #endif
  397. #if (HAS_V33)
  398.     CPU0(V33,       v33,      1,  0,1.20,NEC_INT_NONE,       -1000,           NEC_NMI_INT,    20,      0,20,LE,1, 5,20    ),
  399. #endif
  400. #if (HAS_I8035)
  401.     CPU0(I8035,    i8035,     1,  0,1.00,I8035_IGNORE_INT,  I8035_EXT_INT,  -1,               16,      0,16,LE,1, 2,16    ),
  402. #endif
  403. #if (HAS_I8039)
  404.     CPU0(I8039,    i8039,     1,  0,1.00,I8039_IGNORE_INT,  I8039_EXT_INT,  -1,               16,      0,16,LE,1, 2,16    ),
  405. #endif
  406. #if (HAS_I8048)
  407.     CPU0(I8048,    i8048,     1,  0,1.00,I8048_IGNORE_INT,  I8048_EXT_INT,  -1,               16,      0,16,LE,1, 2,16    ),
  408. #endif
  409. #if (HAS_N7751)
  410.     CPU0(N7751,    n7751,     1,  0,1.00,N7751_IGNORE_INT,  N7751_EXT_INT,  -1,               16,      0,16,LE,1, 2,16    ),
  411. #endif
  412. #if (HAS_M6800)
  413.     CPU0(M6800,    m6800,     1,  0,1.00,M6800_INT_NONE,    M6800_INT_IRQ,  M6800_INT_NMI,  16,      0,16,BE,1, 4,16    ),
  414. #endif
  415. #if (HAS_M6801)
  416.     CPU0(M6801,    m6801,     1,  0,1.00,M6801_INT_NONE,    M6801_INT_IRQ,  M6801_INT_NMI,  16,      0,16,BE,1, 4,16    ),
  417. #endif
  418. #if (HAS_M6802)
  419.     CPU0(M6802,    m6802,     1,  0,1.00,M6802_INT_NONE,    M6802_INT_IRQ,  M6802_INT_NMI,  16,      0,16,BE,1, 4,16    ),
  420. #endif
  421. #if (HAS_M6803)
  422.     CPU0(M6803,    m6803,     1,  0,1.00,M6803_INT_NONE,    M6803_INT_IRQ,  M6803_INT_NMI,  16,      0,16,BE,1, 4,16    ),
  423. #endif
  424. #if (HAS_M6808)
  425.     CPU0(M6808,    m6808,     1,  0,1.00,M6808_INT_NONE,    M6808_INT_IRQ,  M6808_INT_NMI,  16,      0,16,BE,1, 4,16    ),
  426. #endif
  427. #if (HAS_HD63701)
  428.     CPU0(HD63701,  hd63701,  1,  0,1.00,HD63701_INT_NONE,  HD63701_INT_IRQ,HD63701_INT_NMI,16,      0,16,BE,1, 4,16    ),
  429. #endif
  430. #if (HAS_NSC8105)
  431.     CPU0(NSC8105,  nsc8105,  1,  0,1.00,NSC8105_INT_NONE,  NSC8105_INT_IRQ,NSC8105_INT_NMI,16,      0,16,BE,1, 4,16    ),
  432. #endif
  433. #if (HAS_M6805)
  434.     CPU0(M6805,    m6805,     1,  0,1.00,M6805_INT_NONE,    M6805_INT_IRQ,  -1,               16,      0,11,BE,1, 3,16    ),
  435. #endif
  436. #if (HAS_M68705)
  437.     CPU0(M68705,   m68705,     1,  0,1.00,M68705_INT_NONE,   M68705_INT_IRQ, -1,               16,      0,11,BE,1, 3,16    ),
  438. #endif
  439. #if (HAS_HD63705)
  440.     CPU0(HD63705,  hd63705,  8,  0,1.00,HD63705_INT_NONE,  HD63705_INT_IRQ,-1,               16,      0,16,BE,1, 3,16    ),
  441. #endif
  442. #if (HAS_HD6309)
  443.     CPU0(HD6309,   hd6309,     2,  0,1.00,HD6309_INT_NONE,   HD6309_INT_IRQ, HD6309_INT_NMI, 16,      0,16,BE,1, 4,16    ),
  444. #endif
  445. #if (HAS_M6809)
  446.     CPU0(M6809,    m6809,     2,  0,1.00,M6809_INT_NONE,    M6809_INT_IRQ,  M6809_INT_NMI,  16,      0,16,BE,1, 4,16    ),
  447. #endif
  448. #if (HAS_KONAMI)
  449.     CPU0(KONAMI,   konami,     2,  0,1.00,KONAMI_INT_NONE,   KONAMI_INT_IRQ, KONAMI_INT_NMI, 16,      0,16,BE,1, 4,16    ),
  450. #endif
  451. #if (HAS_M68000)
  452.     CPU0(M68000,   m68000,     8, -1,1.00,MC68000_INT_NONE,  -1,               -1,               24bew, 0,24,BE,2,10,24BEW),
  453. #endif
  454. #if (HAS_M68010)
  455.     CPU0(M68010,   m68010,     8, -1,1.00,MC68010_INT_NONE,  -1,               -1,               24bew, 0,24,BE,2,10,24BEW),
  456. #endif
  457. #if (HAS_M68EC020)
  458.     CPU0(M68EC020, m68ec020, 8, -1,1.00,MC68EC020_INT_NONE,-1,               -1,               24bew, 0,24,BE,2,10,24BEW),
  459. #endif
  460. #if (HAS_M68020)
  461.     CPU0(M68020,   m68020,     8, -1,1.00,MC68020_INT_NONE,  -1,               -1,               24bew, 0,24,BE,2,10,24BEW),
  462. #endif
  463. #if (HAS_T11)
  464.     CPU0(T11,       t11,      4,  0,1.00,T11_INT_NONE,       -1,               -1,               16lew, 0,16,LE,2, 6,16LEW),
  465. #endif
  466. #if (HAS_S2650)
  467.     CPU0(S2650,    s2650,     2,  0,1.00,S2650_INT_NONE,    -1,               -1,               16,      0,15,LE,1, 3,16    ),
  468. #endif
  469. #if (HAS_TMS34010)
  470.     CPU2(TMS34010, tms34010, 2,  0,1.00,TMS34010_INT_NONE, TMS34010_INT1,  -1,               29,      3,29,LE,2,10,29    ),
  471. #endif
  472. #if (HAS_TMS9900)
  473.     CPU0(TMS9900,  tms9900,  1,  0,1.00,TMS9900_NONE,       -1,               -1,               16bew, 0,16,BE,2, 6,16BEW),
  474. #endif
  475. #if (HAS_TMS9940)
  476.     CPU0(TMS9940,  tms9940,  1,  0,1.00,TMS9940_NONE,       -1,               -1,               16bew, 0,16,BE,2, 6,16BEW),
  477. #endif
  478. #if (HAS_TMS9980)
  479.     CPU0(TMS9980,  tms9980a, 1,  0,1.00,TMS9980A_NONE,       -1,               -1,               16,      0,16,BE,1, 6,16    ),
  480. #endif
  481. #if (HAS_TMS9985)
  482.     CPU0(TMS9985,  tms9985,  1,  0,1.00,TMS9985_NONE,       -1,               -1,               16,      0,16,BE,1, 6,16    ),
  483. #endif
  484. #if (HAS_TMS9989)
  485.     CPU0(TMS9989,  tms9989,  1,  0,1.00,TMS9989_NONE,       -1,               -1,               16,      0,16,BE,1, 6,16    ),
  486. #endif
  487. #if (HAS_TMS9995)
  488.     CPU0(TMS9995,  tms9995,  1,  0,1.00,TMS9995_NONE,       -1,               -1,               16,      0,16,BE,1, 6,16    ),
  489. #endif
  490. #if (HAS_TMS99105A)
  491.     CPU0(TMS99105A,tms99105a,1,  0,1.00,TMS99105A_NONE,    -1,               -1,               16bew, 0,16,BE,2, 6,16BEW),
  492. #endif
  493. #if (HAS_TMS99110A)
  494.     CPU0(TMS99110A,tms99110a,1,  0,1.00,TMS99110A_NONE,    -1,               -1,               16bew, 0,16,BE,2, 6,16BEW),
  495. #endif
  496. #if (HAS_Z8000)
  497.     CPU0(Z8000,    z8000,     2,  0,1.00,Z8000_INT_NONE,    Z8000_NVI,       Z8000_NMI,       16bew, 0,16,BE,2, 6,16BEW),
  498. #endif
  499. #if (HAS_TMS320C10)
  500.     CPU0(TMS320C10,tms320c10,2,  0,1.00,TMS320C10_INT_NONE,-1,               -1,               16,     -1,16,BE,2, 4,16    ),
  501. #endif
  502. #if (HAS_CCPU)
  503.     CPU0(CCPU,       ccpu,     2,  0,1.00,0,                   -1,               -1,               16,      0,15,LE,1, 3,16    ),
  504. #endif
  505. #if (HAS_PDP1)
  506.     CPU0(PDP1,       pdp1,     0,  0,1.00,0,                   -1,               -1,               16,      0,18,LE,1, 3,16    ),
  507. #endif
  508. #if (HAS_ADSP2100)
  509. /* IMO we should rename all *_ICount to *_icount - ie. no mixed case */
  510. #define adsp2100_ICount adsp2100_icount
  511.     CPU0(ADSP2100, adsp2100, 4,  0,1.00,ADSP2100_INT_NONE, -1,               -1,               16lew,-1,14,LE,2, 4,16LEW),
  512. #endif
  513. #if (HAS_MIPS)
  514.     CPU0(MIPS,       mips,     8, -1,1.00,MIPS_INT_NONE,       MIPS_INT_NONE,  MIPS_INT_NONE,  32lew, 0,32,LE,4, 4,32LEW),
  515. #endif
  516. };
  517.  
  518. void cpu_init(void)
  519. {
  520.     int i;
  521.  
  522.     /* Verify the order of entries in the cpuintf[] array */
  523.     for( i = 0; i < CPU_COUNT; i++ )
  524.     {
  525.         if( cpuintf[i].cpu_num != i )
  526.         {
  527. logerror("CPU #%d [%s] wrong ID %d: check enum CPU_... in src/driver.h!\n", i, cputype_name(i), cpuintf[i].cpu_num);
  528.             exit(1);
  529.         }
  530.     }
  531.  
  532.     /* count how many CPUs we have to emulate */
  533.     totalcpu = 0;
  534.  
  535.     while (totalcpu < MAX_CPU)
  536.     {
  537.         if( CPU_TYPE(totalcpu) == CPU_DUMMY ) break;
  538.         totalcpu++;
  539.     }
  540.  
  541.     /* zap the CPU data structure */
  542.     memset(cpu, 0, sizeof(cpu));
  543.  
  544.     /* Set up the interface functions */
  545.     for (i = 0; i < MAX_CPU; i++)
  546.         cpu[i].intf = &cpuintf[CPU_TYPE(i)];
  547.  
  548.     /* reset the timer system */
  549.     timer_init();
  550.     timeslice_timer = refresh_timer = vblank_timer = NULL;
  551. }
  552.  
  553. void cpu_run(void)
  554. {
  555.     int i;
  556.  
  557.     /* determine which CPUs need a context switch */
  558.     for (i = 0; i < totalcpu; i++)
  559.     {
  560.         int j, size;
  561.  
  562.         /* allocate a context buffer for the CPU */
  563.         size = GETCONTEXT(i,NULL);
  564.         if( size == 0 )
  565.         {
  566.             /* That can't really be true */
  567. logerror("CPU #%d claims to need no context buffer!\n", i);
  568.             raise( SIGABRT );
  569.         }
  570.  
  571.         cpu[i].context = malloc( size );
  572.         if( cpu[i].context == NULL )
  573.         {
  574.             /* That's really bad :( */
  575. logerror("CPU #%d failed to allocate context buffer (%d bytes)!\n", i, size);
  576.             raise( SIGABRT );
  577.         }
  578.  
  579.         /* Zap the context buffer */
  580.         memset(cpu[i].context, 0, size );
  581.  
  582.  
  583.         /* Save if there is another CPU of the same type */
  584.         cpu[i].save_context = 0;
  585.  
  586.         for (j = 0; j < totalcpu; j++)
  587.             if ( i != j && !strcmp(cpunum_core_file(i),cpunum_core_file(j)) )
  588.                 cpu[i].save_context = 1;
  589.  
  590.         #ifdef MAME_DEBUG
  591.  
  592.         /* or if we're running with the debugger */
  593.         {
  594.             extern int mame_debug;
  595.             cpu[i].save_context |= mame_debug;
  596.         }
  597.  
  598.         #endif
  599.  
  600.         for( j = 0; j < MAX_IRQ_LINES; j++ )
  601.         {
  602.             irq_line_state[i * MAX_IRQ_LINES + j] = CLEAR_LINE;
  603.             irq_line_vector[i * MAX_IRQ_LINES + j] = cpuintf[CPU_TYPE(i)].default_vector;
  604.         }
  605.     }
  606.  
  607. #ifdef    MAME_DEBUG
  608.     /* Initialize the debugger */
  609.     if( mame_debug )
  610.         mame_debug_init();
  611. #endif
  612.  
  613.  
  614. reset:
  615.     /* read hi scores information from hiscore.dat */
  616.     hs_open(Machine->gamedrv->name);
  617.     hs_init();
  618.  
  619.     /* initialize the various timers (suspends all CPUs at startup) */
  620.     cpu_inittimers();
  621.     watchdog_counter = -1;
  622.  
  623.     /* reset sound chips */
  624.     sound_reset();
  625.  
  626.     /* enable all CPUs (except for audio CPUs if the sound is off) */
  627.     for (i = 0; i < totalcpu; i++)
  628.     {
  629.         if (!CPU_AUDIO(i) || Machine->sample_rate != 0)
  630.         {
  631.             timer_suspendcpu(i, 0, SUSPEND_REASON_RESET);
  632.         }
  633.         else
  634.         {
  635.             timer_suspendcpu(i, 1, SUSPEND_REASON_DISABLE);
  636.         }
  637.     }
  638.  
  639.     have_to_reset = 0;
  640.     vblank = 0;
  641.  
  642. logerror("Machine reset\n");
  643.  
  644.     /* start with interrupts enabled, so the generic routine will work even if */
  645.     /* the machine doesn't have an interrupt enable port */
  646.     for (i = 0;i < MAX_CPU;i++)
  647.     {
  648.         interrupt_enable[i] = 1;
  649.         interrupt_vector[i] = 0xff;
  650.     }
  651.  
  652.     /* do this AFTER the above so init_machine() can use cpu_halt() to hold the */
  653.     /* execution of some CPUs, or disable interrupts */
  654.     if (Machine->drv->init_machine) (*Machine->drv->init_machine)();
  655.  
  656.     /* reset each CPU */
  657.     for (i = 0; i < totalcpu; i++)
  658.     {
  659.         /* swap memory contexts and reset */
  660.         memorycontextswap(i);
  661.         if (cpu[i].save_context) SETCONTEXT(i, cpu[i].context);
  662.         activecpu = i;
  663.         RESET(i);
  664.  
  665.         /* Set the irq callback for the cpu */
  666.         SETIRQCALLBACK(i,cpu_irq_callbacks[i]);
  667.  
  668.         /* save the CPU context if necessary */
  669.         if (cpu[i].save_context) GETCONTEXT (i, cpu[i].context);
  670.  
  671.         /* reset the total number of cycles */
  672.         cpu[i].totalcycles = 0;
  673.     }
  674.  
  675.     /* reset the globals */
  676.     cpu_vblankreset();
  677.     current_frame = 0;
  678.  
  679.     /* loop until the user quits */
  680.     usres = 0;
  681.     while (usres == 0)
  682.     {
  683.         int cpunum;
  684.  
  685.         /* was machine_reset() called? */
  686.         if (have_to_reset)
  687.         {
  688. #ifdef MESS
  689.             if (Machine->drv->stop_machine) (*Machine->drv->stop_machine)();
  690. #endif
  691.             goto reset;
  692.         }
  693.         profiler_mark(PROFILER_EXTRA);
  694.  
  695. #if SAVE_STATE_TEST
  696.         {
  697.             if( keyboard_pressed_memory(KEYCODE_S) )
  698.             {
  699.                 void *s = state_create(Machine->gamedrv->name);
  700.                 if( s )
  701.                 {
  702.                     for( cpunum = 0; cpunum < totalcpu; cpunum++ )
  703.                     {
  704.                         activecpu = cpunum;
  705.                         memorycontextswap(activecpu);
  706.                         if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  707.                         /* make sure any bank switching is reset */
  708.                         SET_OP_BASE(activecpu, GETPC(activecpu));
  709.                         if( cpu[activecpu].intf->cpu_state_save )
  710.                             (*cpu[activecpu].intf->cpu_state_save)(s);
  711.                     }
  712.                     state_close(s);
  713.                 }
  714.             }
  715.  
  716.             if( keyboard_pressed_memory(KEYCODE_L) )
  717.             {
  718.                 void *s = state_open(Machine->gamedrv->name);
  719.                 if( s )
  720.                 {
  721.                     for( cpunum = 0; cpunum < totalcpu; cpunum++ )
  722.                     {
  723.                         activecpu = cpunum;
  724.                         memorycontextswap(activecpu);
  725.                         if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  726.                         /* make sure any bank switching is reset */
  727.                         SET_OP_BASE(activecpu, GETPC(activecpu));
  728.                         if( cpu[activecpu].intf->cpu_state_load )
  729.                             (*cpu[activecpu].intf->cpu_state_load)(s);
  730.                         /* update the contexts */
  731.                         if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  732.                     }
  733.                     state_close(s);
  734.                 }
  735.             }
  736.         }
  737. #endif
  738.         /* ask the timer system to schedule */
  739.         if (timer_schedule_cpu(&cpunum, &cycles_running))
  740.         {
  741.             int ran;
  742.  
  743.  
  744.             /* switch memory and CPU contexts */
  745.             activecpu = cpunum;
  746.             memorycontextswap(activecpu);
  747.             if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  748.  
  749.             /* make sure any bank switching is reset */
  750.             SET_OP_BASE(activecpu, GETPC(activecpu));
  751.  
  752.             /* run for the requested number of cycles */
  753.             profiler_mark(PROFILER_CPU1 + cpunum);
  754.             ran = EXECUTE(activecpu, cycles_running);
  755.             profiler_mark(PROFILER_END);
  756.  
  757.             /* update based on how many cycles we really ran */
  758.             cpu[activecpu].totalcycles += ran;
  759.  
  760.             /* update the contexts */
  761.             if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  762.             activecpu = -1;
  763.  
  764.             /* update the timer with how long we actually ran */
  765.             timer_update_cpu(cpunum, ran);
  766.         }
  767.  
  768.         profiler_mark(PROFILER_END);
  769.     }
  770.  
  771.     /* write hi scores to disk - No scores saving if cheat */
  772.     hs_close();
  773.  
  774. #ifdef MESS
  775.     if (Machine->drv->stop_machine) (*Machine->drv->stop_machine)();
  776. #endif
  777.  
  778. #ifdef    MAME_DEBUG
  779.     /* Shut down the debugger */
  780.     if( mame_debug )
  781.         mame_debug_exit();
  782. #endif
  783.  
  784.     /* shut down the CPU cores */
  785.     for (i = 0; i < totalcpu; i++)
  786.     {
  787.         /* if the CPU core defines an exit function, call it now */
  788.         if( cpu[i].intf->exit )
  789.             (*cpu[i].intf->exit)();
  790.  
  791.         /* free the context buffer for that CPU */
  792.         if( cpu[i].context )
  793.         {
  794.             free( cpu[i].context );
  795.             cpu[i].context = NULL;
  796.         }
  797.     }
  798.     totalcpu = 0;
  799. }
  800.  
  801.  
  802.  
  803.  
  804. /***************************************************************************
  805.  
  806.   Use this function to initialize, and later maintain, the watchdog. For
  807.   convenience, when the machine is reset, the watchdog is disabled. If you
  808.   call this function, the watchdog is initialized, and from that point
  809.   onwards, if you don't call it at least once every 10 video frames, the
  810.   machine will be reset.
  811.  
  812. ***************************************************************************/
  813. WRITE_HANDLER( watchdog_reset_w )
  814. {
  815.     watchdog_counter = Machine->drv->frames_per_second;
  816. }
  817.  
  818. READ_HANDLER( watchdog_reset_r )
  819. {
  820.     watchdog_counter = Machine->drv->frames_per_second;
  821.     return 0;
  822. }
  823.  
  824.  
  825.  
  826. /***************************************************************************
  827.  
  828.   This function resets the machine (the reset will not take place
  829.   immediately, it will be performed at the end of the active CPU's time
  830.   slice)
  831.  
  832. ***************************************************************************/
  833. void machine_reset(void)
  834. {
  835.     /* write hi scores to disk - No scores saving if cheat */
  836.     hs_close();
  837.  
  838.     have_to_reset = 1;
  839. }
  840.  
  841.  
  842.  
  843. /***************************************************************************
  844.  
  845.   Use this function to reset a specified CPU immediately
  846.  
  847. ***************************************************************************/
  848. void cpu_set_reset_line(int cpunum,int state)
  849. {
  850.     timer_set(TIME_NOW, (cpunum & 7) | (state << 3), cpu_resetcallback);
  851. }
  852.  
  853.  
  854. /***************************************************************************
  855.  
  856.   Use this function to control the HALT line on a CPU
  857.  
  858. ***************************************************************************/
  859. void cpu_set_halt_line(int cpunum,int state)
  860. {
  861.     timer_set(TIME_NOW, (cpunum & 7) | (state << 3), cpu_haltcallback);
  862. }
  863.  
  864.  
  865. /***************************************************************************
  866.  
  867.   This function returns CPUNUM current status  (running or halted)
  868.  
  869. ***************************************************************************/
  870. int cpu_getstatus(int cpunum)
  871. {
  872.     if (cpunum >= MAX_CPU) return 0;
  873.  
  874.     return !timer_iscpususpended(cpunum,
  875.             SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE);
  876. }
  877.  
  878.  
  879.  
  880. int cpu_getactivecpu(void)
  881. {
  882.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  883.     return cpunum;
  884. }
  885.  
  886. void cpu_setactivecpu(int cpunum)
  887. {
  888.     activecpu = cpunum;
  889. }
  890.  
  891. int cpu_gettotalcpu(void)
  892. {
  893.     return totalcpu;
  894. }
  895.  
  896.  
  897.  
  898. unsigned cpu_get_pc(void)
  899. {
  900.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  901.     return GETPC(cpunum);
  902. }
  903.  
  904. void cpu_set_pc(unsigned val)
  905. {
  906.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  907.     SETPC(cpunum,val);
  908. }
  909.  
  910. unsigned cpu_get_sp(void)
  911. {
  912.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  913.     return GETSP(cpunum);
  914. }
  915.  
  916. void cpu_set_sp(unsigned val)
  917. {
  918.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  919.     SETSP(cpunum,val);
  920. }
  921.  
  922. /* these are available externally, for the timer system */
  923. int cycles_currently_ran(void)
  924. {
  925.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  926.     return cycles_running - ICOUNT(cpunum);
  927. }
  928.  
  929. int cycles_left_to_run(void)
  930. {
  931.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  932.     return ICOUNT(cpunum);
  933. }
  934.  
  935.  
  936.  
  937. /***************************************************************************
  938.  
  939.   Returns the number of CPU cycles since the last reset of the CPU
  940.  
  941.   IMPORTANT: this value wraps around in a relatively short time.
  942.   For example, for a 6Mhz CPU, it will wrap around in
  943.   2^32/6000000 = 716 seconds = 12 minutes.
  944.   Make sure you don't do comparisons between values returned by this
  945.   function, but only use the difference (which will be correct regardless
  946.   of wraparound).
  947.  
  948. ***************************************************************************/
  949. int cpu_gettotalcycles(void)
  950. {
  951.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  952.     return cpu[cpunum].totalcycles + cycles_currently_ran();
  953. }
  954.  
  955.  
  956.  
  957. /***************************************************************************
  958.  
  959.   Returns the number of CPU cycles before the next interrupt handler call
  960.  
  961. ***************************************************************************/
  962. int cpu_geticount(void)
  963. {
  964.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  965.     int result = TIME_TO_CYCLES(cpunum, cpu[cpunum].vblankint_period - timer_timeelapsed(cpu[cpunum].vblankint_timer));
  966.     return (result < 0) ? 0 : result;
  967. }
  968.  
  969.  
  970.  
  971. /***************************************************************************
  972.  
  973.   Returns the number of CPU cycles before the end of the current video frame
  974.  
  975. ***************************************************************************/
  976. int cpu_getfcount(void)
  977. {
  978.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  979.     int result = TIME_TO_CYCLES(cpunum, refresh_period - timer_timeelapsed(refresh_timer));
  980.     return (result < 0) ? 0 : result;
  981. }
  982.  
  983.  
  984.  
  985. /***************************************************************************
  986.  
  987.   Returns the number of CPU cycles in one video frame
  988.  
  989. ***************************************************************************/
  990. int cpu_getfperiod(void)
  991. {
  992.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  993.     return TIME_TO_CYCLES(cpunum, refresh_period);
  994. }
  995.  
  996.  
  997.  
  998. /***************************************************************************
  999.  
  1000.   Scales a given value by the ratio of fcount / fperiod
  1001.  
  1002. ***************************************************************************/
  1003. int cpu_scalebyfcount(int value)
  1004. {
  1005.     int result = (int)((double)value * timer_timeelapsed(refresh_timer) * refresh_period_inv);
  1006.     if (value >= 0) return (result < value) ? result : value;
  1007.     else return (result > value) ? result : value;
  1008. }
  1009.  
  1010.  
  1011.  
  1012. /***************************************************************************
  1013.  
  1014.   Returns the current scanline, or the time until a specific scanline
  1015.  
  1016.   Note: cpu_getscanline() counts from 0, 0 being the first visible line. You
  1017.   might have to adjust this value to match the hardware, since in many cases
  1018.   the first visible line is >0.
  1019.  
  1020. ***************************************************************************/
  1021. int cpu_getscanline(void)
  1022. {
  1023.     return (int)(timer_timeelapsed(refresh_timer) * scanline_period_inv);
  1024. }
  1025.  
  1026.  
  1027. double cpu_getscanlinetime(int scanline)
  1028. {
  1029.     double ret;
  1030.     double scantime = timer_starttime(refresh_timer) + (double)scanline * scanline_period;
  1031.     double abstime = timer_get_time();
  1032.     if (abstime >= scantime) scantime += TIME_IN_HZ(Machine->drv->frames_per_second);
  1033.     ret = scantime - abstime;
  1034.     if (ret < TIME_IN_NSEC(1))
  1035.     {
  1036.         ret = TIME_IN_HZ(Machine->drv->frames_per_second);
  1037.     }
  1038.  
  1039.     return ret;
  1040. }
  1041.  
  1042.  
  1043. double cpu_getscanlineperiod(void)
  1044. {
  1045.     return scanline_period;
  1046. }
  1047.  
  1048.  
  1049. /***************************************************************************
  1050.  
  1051.   Returns the number of cycles in a scanline
  1052.  
  1053.  ***************************************************************************/
  1054. int cpu_getscanlinecycles(void)
  1055. {
  1056.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1057.     return TIME_TO_CYCLES(cpunum, scanline_period);
  1058. }
  1059.  
  1060.  
  1061. /***************************************************************************
  1062.  
  1063.   Returns the number of cycles since the beginning of this frame
  1064.  
  1065.  ***************************************************************************/
  1066. int cpu_getcurrentcycles(void)
  1067. {
  1068.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1069.     return TIME_TO_CYCLES(cpunum, timer_timeelapsed(refresh_timer));
  1070. }
  1071.  
  1072.  
  1073. /***************************************************************************
  1074.  
  1075.   Returns the current horizontal beam position in pixels
  1076.  
  1077.  ***************************************************************************/
  1078. int cpu_gethorzbeampos(void)
  1079. {
  1080.     double elapsed_time = timer_timeelapsed(refresh_timer);
  1081.     int scanline = (int)(elapsed_time * scanline_period_inv);
  1082.     double time_since_scanline = elapsed_time -
  1083.                          (double)scanline * scanline_period;
  1084.     return (int)(time_since_scanline * scanline_period_inv *
  1085.                          (double)Machine->drv->screen_width);
  1086. }
  1087.  
  1088.  
  1089. /***************************************************************************
  1090.  
  1091.   Returns the number of times the interrupt handler will be called before
  1092.   the end of the current video frame. This can be useful to interrupt
  1093.   handlers to synchronize their operation. If you call this from outside
  1094.   an interrupt handler, add 1 to the result, i.e. if it returns 0, it means
  1095.   that the interrupt handler will be called once.
  1096.  
  1097. ***************************************************************************/
  1098. int cpu_getiloops(void)
  1099. {
  1100.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1101.     return cpu[cpunum].iloops;
  1102. }
  1103.  
  1104.  
  1105.  
  1106. /***************************************************************************
  1107.  
  1108.   Interrupt handling
  1109.  
  1110. ***************************************************************************/
  1111.  
  1112. /***************************************************************************
  1113.  
  1114.   These functions are called when a cpu calls the callback sent to it's
  1115.   set_irq_callback function. It clears the irq line if the current state
  1116.   is HOLD_LINE and returns the interrupt vector for that line.
  1117.  
  1118. ***************************************************************************/
  1119. static int cpu_0_irq_callback(int irqline)
  1120. {
  1121.     if( irq_line_state[0 * MAX_IRQ_LINES + irqline] == HOLD_LINE )
  1122.     {
  1123.         SETIRQLINE(0, irqline, CLEAR_LINE);
  1124.         irq_line_state[0 * MAX_IRQ_LINES + irqline] = CLEAR_LINE;
  1125.     }
  1126.     LOG(("cpu_0_irq_callback(%d) $%04x\n", irqline, irq_line_vector[0 * MAX_IRQ_LINES + irqline]));
  1127.     return irq_line_vector[0 * MAX_IRQ_LINES + irqline];
  1128. }
  1129.  
  1130. static int cpu_1_irq_callback(int irqline)
  1131. {
  1132.     if( irq_line_state[1 * MAX_IRQ_LINES + irqline] == HOLD_LINE )
  1133.     {
  1134.         SETIRQLINE(1, irqline, CLEAR_LINE);
  1135.         irq_line_state[1 * MAX_IRQ_LINES + irqline] = CLEAR_LINE;
  1136.     }
  1137.     LOG(("cpu_1_irq_callback(%d) $%04x\n", irqline, irq_line_vector[1 * MAX_IRQ_LINES + irqline]));
  1138.     return irq_line_vector[1 * MAX_IRQ_LINES + irqline];
  1139. }
  1140.  
  1141. static int cpu_2_irq_callback(int irqline)
  1142. {
  1143.     if( irq_line_state[2 * MAX_IRQ_LINES + irqline] == HOLD_LINE )
  1144.     {
  1145.         SETIRQLINE(2, irqline, CLEAR_LINE);
  1146.         irq_line_state[2 * MAX_IRQ_LINES + irqline] = CLEAR_LINE;
  1147.     }
  1148.     LOG(("cpu_2_irq_callback(%d) $%04x\n", irqline, irq_line_vector[2 * MAX_IRQ_LINES + irqline]));
  1149.     return irq_line_vector[2 * MAX_IRQ_LINES + irqline];
  1150. }
  1151.  
  1152. static int cpu_3_irq_callback(int irqline)
  1153. {
  1154.     if( irq_line_state[3 * MAX_IRQ_LINES + irqline] == HOLD_LINE )
  1155.     {
  1156.         SETIRQLINE(3, irqline, CLEAR_LINE);
  1157.         irq_line_state[3 * MAX_IRQ_LINES + irqline] = CLEAR_LINE;
  1158.     }
  1159.     LOG(("cpu_3_irq_callback(%d) $%04x\n", irqline, irq_line_vector[2 * MAX_IRQ_LINES + irqline]));
  1160.     return irq_line_vector[3 * MAX_IRQ_LINES + irqline];
  1161. }
  1162.  
  1163. /***************************************************************************
  1164.  
  1165.   This function is used to generate internal interrupts (TMS34010)
  1166.  
  1167. ***************************************************************************/
  1168. void cpu_generate_internal_interrupt(int cpunum, int type)
  1169. {
  1170.     timer_set(TIME_NOW, (cpunum & 7) | (type << 3), cpu_internalintcallback);
  1171. }
  1172.  
  1173.  
  1174. /***************************************************************************
  1175.  
  1176.   Use this functions to set the vector for a irq line of a CPU
  1177.  
  1178. ***************************************************************************/
  1179. void cpu_irq_line_vector_w(int cpunum, int irqline, int vector)
  1180. {
  1181.     cpunum &= (MAX_CPU - 1);
  1182.     irqline &= (MAX_IRQ_LINES - 1);
  1183.     if( irqline < cpu[cpunum].intf->num_irqs )
  1184.     {
  1185.         LOG(("cpu_irq_line_vector_w(%d,%d,$%04x)\n",cpunum,irqline,vector));
  1186.         irq_line_vector[cpunum * MAX_IRQ_LINES + irqline] = vector;
  1187.         return;
  1188.     }
  1189.     LOG(("cpu_irq_line_vector_w CPU#%d irqline %d > max irq lines\n", cpunum, irqline));
  1190. }
  1191.  
  1192. /***************************************************************************
  1193.  
  1194.   Use these functions to set the vector (data) for a irq line (offset)
  1195.   of CPU #0 to #3
  1196.  
  1197. ***************************************************************************/
  1198. WRITE_HANDLER( cpu_0_irq_line_vector_w ) { cpu_irq_line_vector_w(0, offset, data); }
  1199. WRITE_HANDLER( cpu_1_irq_line_vector_w ) { cpu_irq_line_vector_w(1, offset, data); }
  1200. WRITE_HANDLER( cpu_2_irq_line_vector_w ) { cpu_irq_line_vector_w(2, offset, data); }
  1201. WRITE_HANDLER( cpu_3_irq_line_vector_w ) { cpu_irq_line_vector_w(3, offset, data); }
  1202. WRITE_HANDLER( cpu_4_irq_line_vector_w ) { cpu_irq_line_vector_w(4, offset, data); }
  1203. WRITE_HANDLER( cpu_5_irq_line_vector_w ) { cpu_irq_line_vector_w(5, offset, data); }
  1204. WRITE_HANDLER( cpu_6_irq_line_vector_w ) { cpu_irq_line_vector_w(6, offset, data); }
  1205. WRITE_HANDLER( cpu_7_irq_line_vector_w ) { cpu_irq_line_vector_w(7, offset, data); }
  1206.  
  1207. /***************************************************************************
  1208.  
  1209.   Use this function to set the state the NMI line of a CPU
  1210.  
  1211. ***************************************************************************/
  1212. void cpu_set_nmi_line(int cpunum, int state)
  1213. {
  1214.     /* don't trigger interrupts on suspended CPUs */
  1215.     if (cpu_getstatus(cpunum) == 0) return;
  1216.  
  1217.     LOG(("cpu_set_nmi_line(%d,%d)\n",cpunum,state));
  1218.     timer_set(TIME_NOW, (cpunum & 7) | (state << 3), cpu_manualnmicallback);
  1219. }
  1220.  
  1221. /***************************************************************************
  1222.  
  1223.   Use this function to set the state of an IRQ line of a CPU
  1224.   The meaning of irqline varies between the different CPU types
  1225.  
  1226. ***************************************************************************/
  1227. void cpu_set_irq_line(int cpunum, int irqline, int state)
  1228. {
  1229.     /* don't trigger interrupts on suspended CPUs */
  1230.     if (cpu_getstatus(cpunum) == 0) return;
  1231.  
  1232.     LOG(("cpu_set_irq_line(%d,%d,%d)\n",cpunum,irqline,state));
  1233.     timer_set(TIME_NOW, (irqline & 7) | ((cpunum & 7) << 3) | (state << 6), cpu_manualirqcallback);
  1234. }
  1235.  
  1236. /***************************************************************************
  1237.  
  1238.   Use this function to cause an interrupt immediately (don't have to wait
  1239.   until the next call to the interrupt handler)
  1240.  
  1241. ***************************************************************************/
  1242. void cpu_cause_interrupt(int cpunum,int type)
  1243. {
  1244.     /* don't trigger interrupts on suspended CPUs */
  1245.     if (cpu_getstatus(cpunum) == 0) return;
  1246.  
  1247.     timer_set(TIME_NOW, (cpunum & 7) | (type << 3), cpu_manualintcallback);
  1248. }
  1249.  
  1250.  
  1251.  
  1252. void cpu_clear_pending_interrupts(int cpunum)
  1253. {
  1254.     timer_set(TIME_NOW, cpunum, cpu_clearintcallback);
  1255. }
  1256.  
  1257.  
  1258.  
  1259. WRITE_HANDLER( interrupt_enable_w )
  1260. {
  1261.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1262.     interrupt_enable[cpunum] = data;
  1263.  
  1264.     /* make sure there are no queued interrupts */
  1265.     if (data == 0) cpu_clear_pending_interrupts(cpunum);
  1266. }
  1267.  
  1268.  
  1269.  
  1270. WRITE_HANDLER( interrupt_vector_w )
  1271. {
  1272.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1273.     if (interrupt_vector[cpunum] != data)
  1274.     {
  1275.         LOG(("CPU#%d interrupt_vector_w $%02x\n", cpunum, data));
  1276.         interrupt_vector[cpunum] = data;
  1277.  
  1278.         /* make sure there are no queued interrupts */
  1279.         cpu_clear_pending_interrupts(cpunum);
  1280.     }
  1281. }
  1282.  
  1283.  
  1284.  
  1285. int interrupt(void)
  1286. {
  1287.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1288.     int val;
  1289.  
  1290.     if (interrupt_enable[cpunum] == 0)
  1291.         return INT_TYPE_NONE(cpunum);
  1292.  
  1293.     val = INT_TYPE_IRQ(cpunum);
  1294.     if (val == -1000)
  1295.         val = interrupt_vector[cpunum];
  1296.  
  1297.     return val;
  1298. }
  1299.  
  1300.  
  1301.  
  1302. int nmi_interrupt(void)
  1303. {
  1304.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1305.  
  1306.     if (interrupt_enable[cpunum] == 0)
  1307.         return INT_TYPE_NONE(cpunum);
  1308.  
  1309.     return INT_TYPE_NMI(cpunum);
  1310. }
  1311.  
  1312.  
  1313.  
  1314. int m68_level1_irq(void)
  1315. {
  1316.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1317.     if (interrupt_enable[cpunum] == 0) return MC68000_INT_NONE;
  1318.     return MC68000_IRQ_1;
  1319. }
  1320. int m68_level2_irq(void)
  1321. {
  1322.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1323.     if (interrupt_enable[cpunum] == 0) return MC68000_INT_NONE;
  1324.     return MC68000_IRQ_2;
  1325. }
  1326. int m68_level3_irq(void)
  1327. {
  1328.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1329.     if (interrupt_enable[cpunum] == 0) return MC68000_INT_NONE;
  1330.     return MC68000_IRQ_3;
  1331. }
  1332. int m68_level4_irq(void)
  1333. {
  1334.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1335.     if (interrupt_enable[cpunum] == 0) return MC68000_INT_NONE;
  1336.     return MC68000_IRQ_4;
  1337. }
  1338. int m68_level5_irq(void)
  1339. {
  1340.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1341.     if (interrupt_enable[cpunum] == 0) return MC68000_INT_NONE;
  1342.     return MC68000_IRQ_5;
  1343. }
  1344. int m68_level6_irq(void)
  1345. {
  1346.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1347.     if (interrupt_enable[cpunum] == 0) return MC68000_INT_NONE;
  1348.     return MC68000_IRQ_6;
  1349. }
  1350. int m68_level7_irq(void)
  1351. {
  1352.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1353.     if (interrupt_enable[cpunum] == 0) return MC68000_INT_NONE;
  1354.     return MC68000_IRQ_7;
  1355. }
  1356.  
  1357.  
  1358.  
  1359. int ignore_interrupt(void)
  1360. {
  1361.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1362.     return INT_TYPE_NONE(cpunum);
  1363. }
  1364.  
  1365.  
  1366.  
  1367. /***************************************************************************
  1368.  
  1369.   CPU timing and synchronization functions.
  1370.  
  1371. ***************************************************************************/
  1372.  
  1373. /* generate a trigger */
  1374. void cpu_trigger(int trigger)
  1375. {
  1376.     timer_trigger(trigger);
  1377. }
  1378.  
  1379. /* generate a trigger after a specific period of time */
  1380. void cpu_triggertime(double duration, int trigger)
  1381. {
  1382.     timer_set(duration, trigger, cpu_trigger);
  1383. }
  1384.  
  1385.  
  1386.  
  1387. /* burn CPU cycles until a timer trigger */
  1388. void cpu_spinuntil_trigger(int trigger)
  1389. {
  1390.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1391.     timer_suspendcpu_trigger(cpunum, trigger);
  1392. }
  1393.  
  1394. /* burn CPU cycles until the next interrupt */
  1395. void cpu_spinuntil_int(void)
  1396. {
  1397.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1398.     cpu_spinuntil_trigger(TRIGGER_INT + cpunum);
  1399. }
  1400.  
  1401. /* burn CPU cycles until our timeslice is up */
  1402. void cpu_spin(void)
  1403. {
  1404.     cpu_spinuntil_trigger(TRIGGER_TIMESLICE);
  1405. }
  1406.  
  1407. /* burn CPU cycles for a specific period of time */
  1408. void cpu_spinuntil_time(double duration)
  1409. {
  1410.     static int timetrig = 0;
  1411.  
  1412.     cpu_spinuntil_trigger(TRIGGER_SUSPENDTIME + timetrig);
  1413.     cpu_triggertime(duration, TRIGGER_SUSPENDTIME + timetrig);
  1414.     timetrig = (timetrig + 1) & 255;
  1415. }
  1416.  
  1417.  
  1418.  
  1419. /* yield our timeslice for a specific period of time */
  1420. void cpu_yielduntil_trigger(int trigger)
  1421. {
  1422.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1423.     timer_holdcpu_trigger(cpunum, trigger);
  1424. }
  1425.  
  1426. /* yield our timeslice until the next interrupt */
  1427. void cpu_yielduntil_int(void)
  1428. {
  1429.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  1430.     cpu_yielduntil_trigger(TRIGGER_INT + cpunum);
  1431. }
  1432.  
  1433. /* yield our current timeslice */
  1434. void cpu_yield(void)
  1435. {
  1436.     cpu_yielduntil_trigger(TRIGGER_TIMESLICE);
  1437. }
  1438.  
  1439. /* yield our timeslice for a specific period of time */
  1440. void cpu_yielduntil_time(double duration)
  1441. {
  1442.     static int timetrig = 0;
  1443.  
  1444.     cpu_yielduntil_trigger(TRIGGER_YIELDTIME + timetrig);
  1445.     cpu_triggertime(duration, TRIGGER_YIELDTIME + timetrig);
  1446.     timetrig = (timetrig + 1) & 255;
  1447. }
  1448.  
  1449.  
  1450.  
  1451. int cpu_getvblank(void)
  1452. {
  1453.     return vblank;
  1454. }
  1455.  
  1456.  
  1457. int cpu_getcurrentframe(void)
  1458. {
  1459.     return current_frame;
  1460. }
  1461.  
  1462.  
  1463. /***************************************************************************
  1464.  
  1465.   Internal CPU event processors.
  1466.  
  1467. ***************************************************************************/
  1468.  
  1469. static void cpu_manualnmicallback(int param)
  1470. {
  1471.     int cpunum, state, oldactive;
  1472.     cpunum = param & 7;
  1473.     state = param >> 3;
  1474.  
  1475.     /* swap to the CPU's context */
  1476.     oldactive = activecpu;
  1477.     activecpu = cpunum;
  1478.     memorycontextswap(activecpu);
  1479.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  1480.  
  1481.     LOG(("cpu_manualnmicallback %d,%d\n",cpunum,state));
  1482.  
  1483.     switch (state)
  1484.     {
  1485.         case PULSE_LINE:
  1486.             SETNMILINE(cpunum,ASSERT_LINE);
  1487.             SETNMILINE(cpunum,CLEAR_LINE);
  1488.             break;
  1489.         case HOLD_LINE:
  1490.         case ASSERT_LINE:
  1491.             SETNMILINE(cpunum,ASSERT_LINE);
  1492.             break;
  1493.         case CLEAR_LINE:
  1494.             SETNMILINE(cpunum,CLEAR_LINE);
  1495.             break;
  1496.         default:
  1497.             logerror("cpu_manualnmicallback cpu #%d unknown state %d\n", cpunum, state);
  1498.     }
  1499.     /* update the CPU's context */
  1500.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  1501.     activecpu = oldactive;
  1502.     if (activecpu >= 0) memorycontextswap(activecpu);
  1503.  
  1504.     /* generate a trigger to unsuspend any CPUs waiting on the interrupt */
  1505.     if (state != CLEAR_LINE)
  1506.         timer_trigger(TRIGGER_INT + cpunum);
  1507. }
  1508.  
  1509. static void cpu_manualirqcallback(int param)
  1510. {
  1511.     int cpunum, irqline, state, oldactive;
  1512.  
  1513.     irqline = param & 7;
  1514.     cpunum = (param >> 3) & 7;
  1515.     state = param >> 6;
  1516.  
  1517.     /* swap to the CPU's context */
  1518.     oldactive = activecpu;
  1519.     activecpu = cpunum;
  1520.     memorycontextswap(activecpu);
  1521.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  1522.  
  1523.     LOG(("cpu_manualirqcallback %d,%d,%d\n",cpunum,irqline,state));
  1524.  
  1525.     irq_line_state[cpunum * MAX_IRQ_LINES + irqline] = state;
  1526.     switch (state)
  1527.     {
  1528.         case PULSE_LINE:
  1529.             SETIRQLINE(cpunum,irqline,ASSERT_LINE);
  1530.             SETIRQLINE(cpunum,irqline,CLEAR_LINE);
  1531.             break;
  1532.         case HOLD_LINE:
  1533.         case ASSERT_LINE:
  1534.             SETIRQLINE(cpunum,irqline,ASSERT_LINE);
  1535.             break;
  1536.         case CLEAR_LINE:
  1537.             SETIRQLINE(cpunum,irqline,CLEAR_LINE);
  1538.             break;
  1539.         default:
  1540.             logerror("cpu_manualirqcallback cpu #%d, line %d, unknown state %d\n", cpunum, irqline, state);
  1541.     }
  1542.  
  1543.     /* update the CPU's context */
  1544.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  1545.     activecpu = oldactive;
  1546.     if (activecpu >= 0) memorycontextswap(activecpu);
  1547.  
  1548.     /* generate a trigger to unsuspend any CPUs waiting on the interrupt */
  1549.     if (state != CLEAR_LINE)
  1550.         timer_trigger(TRIGGER_INT + cpunum);
  1551. }
  1552.  
  1553. static void cpu_internal_interrupt(int cpunum, int type)
  1554. {
  1555.     int oldactive = activecpu;
  1556.  
  1557.     /* swap to the CPU's context */
  1558.     activecpu = cpunum;
  1559.     memorycontextswap(activecpu);
  1560.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  1561.  
  1562.     INTERNAL_INTERRUPT(cpunum, type);
  1563.  
  1564.     /* update the CPU's context */
  1565.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  1566.     activecpu = oldactive;
  1567.     if (activecpu >= 0) memorycontextswap(activecpu);
  1568.  
  1569.     /* generate a trigger to unsuspend any CPUs waiting on the interrupt */
  1570.     timer_trigger(TRIGGER_INT + cpunum);
  1571. }
  1572.  
  1573. static void cpu_internalintcallback(int param)
  1574. {
  1575.     int type = param >> 3;
  1576.     int cpunum = param & 7;
  1577.  
  1578.     LOG(("CPU#%d internal interrupt type $%04x\n", cpunum, type));
  1579.     /* generate the interrupt */
  1580.     cpu_internal_interrupt(cpunum, type);
  1581. }
  1582.  
  1583. static void cpu_generate_interrupt(int cpunum, int (*func)(void), int num)
  1584. {
  1585.     int oldactive = activecpu;
  1586.  
  1587.     /* don't trigger interrupts on suspended CPUs */
  1588.     if (cpu_getstatus(cpunum) == 0) return;
  1589.  
  1590.     /* swap to the CPU's context */
  1591.     activecpu = cpunum;
  1592.     memorycontextswap(activecpu);
  1593.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  1594.  
  1595.     /* cause the interrupt, calling the function if it exists */
  1596.     if (func) num = (*func)();
  1597.  
  1598.     /* wrapper for the new interrupt system */
  1599.     if (num != INT_TYPE_NONE(cpunum))
  1600.     {
  1601.         LOG(("CPU#%d interrupt type $%04x: ", cpunum, num));
  1602.         /* is it the NMI type interrupt of that CPU? */
  1603.         if (num == INT_TYPE_NMI(cpunum))
  1604.         {
  1605.  
  1606.             LOG(("NMI\n"));
  1607.             cpu_manualnmicallback(cpunum | (PULSE_LINE << 3) );
  1608.  
  1609.         }
  1610.         else
  1611.         {
  1612.             int irq_line;
  1613.  
  1614.             switch (CPU_TYPE(cpunum))
  1615.             {
  1616. #if (HAS_Z80)
  1617.             case CPU_Z80:                irq_line = 0; LOG(("Z80 IRQ\n")); break;
  1618. #endif
  1619. #if (HAS_8080)
  1620.             case CPU_8080:
  1621.                 switch (num)
  1622.                 {
  1623.                 case I8080_INTR:        irq_line = 0; LOG(("I8080 INTR\n")); break;
  1624.                 default:                irq_line = 0; LOG(("I8080 unknown\n"));
  1625.                 }
  1626.                 break;
  1627. #endif
  1628. #if (HAS_8085A)
  1629.             case CPU_8085A:
  1630.                 switch (num)
  1631.                 {
  1632.                 case I8085_INTR:        irq_line = 0; LOG(("I8085 INTR\n")); break;
  1633.                 case I8085_RST55:        irq_line = 1; LOG(("I8085 RST55\n")); break;
  1634.                 case I8085_RST65:        irq_line = 2; LOG(("I8085 RST65\n")); break;
  1635.                 case I8085_RST75:        irq_line = 3; LOG(("I8085 RST75\n")); break;
  1636.                 default:                irq_line = 0; LOG(("I8085 unknown\n"));
  1637.                 }
  1638.                 break;
  1639. #endif
  1640. #if (HAS_M6502)
  1641.             case CPU_M6502:             irq_line = 0; LOG(("M6502 IRQ\n")); break;
  1642. #endif
  1643. #if (HAS_M65C02)
  1644.             case CPU_M65C02:            irq_line = 0; LOG(("M65C02 IRQ\n")); break;
  1645. #endif
  1646. #if (HAS_M65SC02)
  1647.             case CPU_M65SC02:            irq_line = 0; LOG(("M65SC02 IRQ\n")); break;
  1648. #endif
  1649. #if (HAS_M65CE02)
  1650.             case CPU_M65CE02:            irq_line = 0; LOG(("M65CE02 IRQ\n")); break;
  1651. #endif
  1652. #if (HAS_M6509)
  1653.             case CPU_M6509:             irq_line = 0; LOG(("M6509 IRQ\n")); break;
  1654. #endif
  1655. #if (HAS_M6510)
  1656.             case CPU_M6510:             irq_line = 0; LOG(("M6510 IRQ\n")); break;
  1657. #endif
  1658. #if (HAS_M6510T)
  1659.             case CPU_M6510T:            irq_line = 0; LOG(("M6510T IRQ\n")); break;
  1660. #endif
  1661. #if (HAS_M7501)
  1662.             case CPU_M7501:             irq_line = 0; LOG(("M7501 IRQ\n")); break;
  1663. #endif
  1664. #if (HAS_M8502)
  1665.             case CPU_M8502:             irq_line = 0; LOG(("M8502 IRQ\n")); break;
  1666. #endif
  1667. #if (HAS_N2A03)
  1668.             case CPU_N2A03:             irq_line = 0; LOG(("N2A03 IRQ\n")); break;
  1669. #endif
  1670. #if (HAS_M4510)
  1671.             case CPU_M4510:             irq_line = 0; LOG(("M4510 IRQ\n")); break;
  1672. #endif
  1673. #if (HAS_H6280)
  1674.             case CPU_H6280:
  1675.                 switch (num)
  1676.                 {
  1677.                 case H6280_INT_IRQ1:    irq_line = 0; LOG(("H6280 INT 1\n")); break;
  1678.                 case H6280_INT_IRQ2:    irq_line = 1; LOG(("H6280 INT 2\n")); break;
  1679.                 case H6280_INT_TIMER:    irq_line = 2; LOG(("H6280 TIMER INT\n")); break;
  1680.                 default:                irq_line = 0; LOG(("H6280 unknown\n"));
  1681.                 }
  1682.                 break;
  1683. #endif
  1684. #if (HAS_I86)
  1685.             case CPU_I86:                irq_line = 0; LOG(("I86 IRQ\n")); break;
  1686. #endif
  1687. #if (HAS_I88)
  1688.             case CPU_I88:                irq_line = 0; LOG(("I88 IRQ\n")); break;
  1689. #endif
  1690. #if (HAS_I186)
  1691.             case CPU_I186:                irq_line = 0; LOG(("I186 IRQ\n")); break;
  1692. #endif
  1693. #if (HAS_I188)
  1694.             case CPU_I188:                irq_line = 0; LOG(("I188 IRQ\n")); break;
  1695. #endif
  1696. #if (HAS_I286)
  1697.             case CPU_I286:                irq_line = 0; LOG(("I286 IRQ\n")); break;
  1698. #endif
  1699. #if (HAS_V20)
  1700.             case CPU_V20:                irq_line = 0; LOG(("V20 IRQ\n")); break;
  1701. #endif
  1702. #if (HAS_V30)
  1703.             case CPU_V30:                irq_line = 0; LOG(("V30 IRQ\n")); break;
  1704. #endif
  1705. #if (HAS_V33)
  1706.             case CPU_V33:                irq_line = 0; LOG(("V33 IRQ\n")); break;
  1707. #endif
  1708. #if (HAS_I8035)
  1709.             case CPU_I8035:             irq_line = 0; LOG(("I8035 IRQ\n")); break;
  1710. #endif
  1711. #if (HAS_I8039)
  1712.             case CPU_I8039:             irq_line = 0; LOG(("I8039 IRQ\n")); break;
  1713. #endif
  1714. #if (HAS_I8048)
  1715.             case CPU_I8048:             irq_line = 0; LOG(("I8048 IRQ\n")); break;
  1716. #endif
  1717. #if (HAS_N7751)
  1718.             case CPU_N7751:             irq_line = 0; LOG(("N7751 IRQ\n")); break;
  1719. #endif
  1720. #if (HAS_M6800)
  1721.             case CPU_M6800:             irq_line = 0; LOG(("M6800 IRQ\n")); break;
  1722. #endif
  1723. #if (HAS_M6801)
  1724.             case CPU_M6801:             irq_line = 0; LOG(("M6801 IRQ\n")); break;
  1725. #endif
  1726. #if (HAS_M6802)
  1727.             case CPU_M6802:             irq_line = 0; LOG(("M6802 IRQ\n")); break;
  1728. #endif
  1729. #if (HAS_M6803)
  1730.             case CPU_M6803:             irq_line = 0; LOG(("M6803 IRQ\n")); break;
  1731. #endif
  1732. #if (HAS_M6808)
  1733.             case CPU_M6808:             irq_line = 0; LOG(("M6808 IRQ\n")); break;
  1734. #endif
  1735. #if (HAS_HD63701)
  1736.             case CPU_HD63701:            irq_line = 0; LOG(("HD63701 IRQ\n")); break;
  1737. #endif
  1738. #if (HAS_M6805)
  1739.             case CPU_M6805:             irq_line = 0; LOG(("M6805 IRQ\n")); break;
  1740. #endif
  1741. #if (HAS_M68705)
  1742.             case CPU_M68705:            irq_line = 0; LOG(("M68705 IRQ\n")); break;
  1743. #endif
  1744. #if (HAS_HD63705)
  1745.             case CPU_HD63705:            irq_line = 0; LOG(("HD68705 IRQ\n")); break;
  1746. #endif
  1747. #if (HAS_HD6309)
  1748.             case CPU_HD6309:
  1749.                 switch (num)
  1750.                 {
  1751.                 case HD6309_INT_IRQ:    irq_line = 0; LOG(("M6309 IRQ\n")); break;
  1752.                 case HD6309_INT_FIRQ:    irq_line = 1; LOG(("M6309 FIRQ\n")); break;
  1753.                 default:                irq_line = 0; LOG(("M6309 unknown\n"));
  1754.                 }
  1755.                 break;
  1756. #endif
  1757. #if (HAS_M6809)
  1758.             case CPU_M6809:
  1759.                 switch (num)
  1760.                 {
  1761.                 case M6809_INT_IRQ:     irq_line = 0; LOG(("M6809 IRQ\n")); break;
  1762.                 case M6809_INT_FIRQ:    irq_line = 1; LOG(("M6809 FIRQ\n")); break;
  1763.                 default:                irq_line = 0; LOG(("M6809 unknown\n"));
  1764.                 }
  1765.                 break;
  1766. #endif
  1767. #if (HAS_KONAMI)
  1768.                 case CPU_KONAMI:
  1769.                 switch (num)
  1770.                 {
  1771.                 case KONAMI_INT_IRQ:    irq_line = 0; LOG(("KONAMI IRQ\n")); break;
  1772.                 case KONAMI_INT_FIRQ:    irq_line = 1; LOG(("KONAMI FIRQ\n")); break;
  1773.                 default:                irq_line = 0; LOG(("KONAMI unknown\n"));
  1774.                 }
  1775.                 break;
  1776. #endif
  1777. #if (HAS_M68000)
  1778.             case CPU_M68000:
  1779.                 switch (num)
  1780.                 {
  1781.                 case MC68000_IRQ_1:     irq_line = 1; LOG(("M68K IRQ1\n")); break;
  1782.                 case MC68000_IRQ_2:     irq_line = 2; LOG(("M68K IRQ2\n")); break;
  1783.                 case MC68000_IRQ_3:     irq_line = 3; LOG(("M68K IRQ3\n")); break;
  1784.                 case MC68000_IRQ_4:     irq_line = 4; LOG(("M68K IRQ4\n")); break;
  1785.                 case MC68000_IRQ_5:     irq_line = 5; LOG(("M68K IRQ5\n")); break;
  1786.                 case MC68000_IRQ_6:     irq_line = 6; LOG(("M68K IRQ6\n")); break;
  1787.                 case MC68000_IRQ_7:     irq_line = 7; LOG(("M68K IRQ7\n")); break;
  1788.                 default:                irq_line = 0; LOG(("M68K unknown\n"));
  1789.                 }
  1790.                 /* until now only auto vector interrupts supported */
  1791.                 num = MC68000_INT_ACK_AUTOVECTOR;
  1792.                 break;
  1793. #endif
  1794. #if (HAS_M68010)
  1795.             case CPU_M68010:
  1796.                 switch (num)
  1797.                 {
  1798.                 case MC68010_IRQ_1:     irq_line = 1; LOG(("M68010 IRQ1\n")); break;
  1799.                 case MC68010_IRQ_2:     irq_line = 2; LOG(("M68010 IRQ2\n")); break;
  1800.                 case MC68010_IRQ_3:     irq_line = 3; LOG(("M68010 IRQ3\n")); break;
  1801.                 case MC68010_IRQ_4:     irq_line = 4; LOG(("M68010 IRQ4\n")); break;
  1802.                 case MC68010_IRQ_5:     irq_line = 5; LOG(("M68010 IRQ5\n")); break;
  1803.                 case MC68010_IRQ_6:     irq_line = 6; LOG(("M68010 IRQ6\n")); break;
  1804.                 case MC68010_IRQ_7:     irq_line = 7; LOG(("M68010 IRQ7\n")); break;
  1805.                 default:                irq_line = 0; LOG(("M68010 unknown\n"));
  1806.                 }
  1807.                 /* until now only auto vector interrupts supported */
  1808.                 num = MC68000_INT_ACK_AUTOVECTOR;
  1809.                 break;
  1810. #endif
  1811. #if (HAS_M68020)
  1812.             case CPU_M68020:
  1813.                 switch (num)
  1814.                 {
  1815.                 case MC68020_IRQ_1:     irq_line = 1; LOG(("M68020 IRQ1\n")); break;
  1816.                 case MC68020_IRQ_2:     irq_line = 2; LOG(("M68020 IRQ2\n")); break;
  1817.                 case MC68020_IRQ_3:     irq_line = 3; LOG(("M68020 IRQ3\n")); break;
  1818.                 case MC68020_IRQ_4:     irq_line = 4; LOG(("M68020 IRQ4\n")); break;
  1819.                 case MC68020_IRQ_5:     irq_line = 5; LOG(("M68020 IRQ5\n")); break;
  1820.                 case MC68020_IRQ_6:     irq_line = 6; LOG(("M68020 IRQ6\n")); break;
  1821.                 case MC68020_IRQ_7:     irq_line = 7; LOG(("M68020 IRQ7\n")); break;
  1822.                 default:                irq_line = 0; LOG(("M68020 unknown\n"));
  1823.                 }
  1824.                 /* until now only auto vector interrupts supported */
  1825.                 num = MC68000_INT_ACK_AUTOVECTOR;
  1826.                 break;
  1827. #endif
  1828. #if (HAS_M68EC020)
  1829.             case CPU_M68EC020:
  1830.                 switch (num)
  1831.                 {
  1832.                 case MC68EC020_IRQ_1:    irq_line = 1; LOG(("M68EC020 IRQ1\n")); break;
  1833.                 case MC68EC020_IRQ_2:    irq_line = 2; LOG(("M68EC020 IRQ2\n")); break;
  1834.                 case MC68EC020_IRQ_3:    irq_line = 3; LOG(("M68EC020 IRQ3\n")); break;
  1835.                 case MC68EC020_IRQ_4:    irq_line = 4; LOG(("M68EC020 IRQ4\n")); break;
  1836.                 case MC68EC020_IRQ_5:    irq_line = 5; LOG(("M68EC020 IRQ5\n")); break;
  1837.                 case MC68EC020_IRQ_6:    irq_line = 6; LOG(("M68EC020 IRQ6\n")); break;
  1838.                 case MC68EC020_IRQ_7:    irq_line = 7; LOG(("M68EC020 IRQ7\n")); break;
  1839.                 default:                irq_line = 0; LOG(("M68EC020 unknown\n"));
  1840.                 }
  1841.                 /* until now only auto vector interrupts supported */
  1842.                 num = MC68000_INT_ACK_AUTOVECTOR;
  1843.                 break;
  1844. #endif
  1845. #if (HAS_T11)
  1846.             case CPU_T11:
  1847.                 switch (num)
  1848.                 {
  1849.                 case T11_IRQ0:            irq_line = 0; LOG(("T11 IRQ0\n")); break;
  1850.                 case T11_IRQ1:            irq_line = 1; LOG(("T11 IRQ1\n")); break;
  1851.                 case T11_IRQ2:            irq_line = 2; LOG(("T11 IRQ2\n")); break;
  1852.                 case T11_IRQ3:            irq_line = 3; LOG(("T11 IRQ3\n")); break;
  1853.                 default:                irq_line = 0; LOG(("T11 unknown\n"));
  1854.                 }
  1855.                 break;
  1856. #endif
  1857. #if (HAS_S2650)
  1858.             case CPU_S2650:             irq_line = 0; LOG(("S2650 IRQ\n")); break;
  1859. #endif
  1860. #if (HAS_TMS34010)
  1861.             case CPU_TMS34010:
  1862.                 switch (num)
  1863.                 {
  1864.                 case TMS34010_INT1:     irq_line = 0; LOG(("TMS34010 INT1\n")); break;
  1865.                 case TMS34010_INT2:     irq_line = 1; LOG(("TMS34010 INT2\n")); break;
  1866.                 default:                irq_line = 0; LOG(("TMS34010 unknown\n"));
  1867.                 }
  1868.                 break;
  1869. #endif
  1870. /*#if (HAS_TMS9900)
  1871.             case CPU_TMS9900:    irq_line = 0; LOG(("TMS9900 IRQ\n")); break;
  1872. #endif*/
  1873. #if (HAS_TMS9900) || (HAS_TMS9940) || (HAS_TMS9980) || (HAS_TMS9985) \
  1874.     || (HAS_TMS9989) || (HAS_TMS9995) || (HAS_TMS99105A) || (HAS_TMS99110A)
  1875.     #if (HAS_TMS9900)
  1876.             case CPU_TMS9900:
  1877.     #endif
  1878.     #if (HAS_TMS9940)
  1879.             case CPU_TMS9940:
  1880.     #endif
  1881.     #if (HAS_TMS9980)
  1882.             case CPU_TMS9980:
  1883.     #endif
  1884.     #if (HAS_TMS9985)
  1885.             case CPU_TMS9985:
  1886.     #endif
  1887.     #if (HAS_TMS9989)
  1888.             case CPU_TMS9989:
  1889.     #endif
  1890.     #if (HAS_TMS9995)
  1891.             case CPU_TMS9995:
  1892.     #endif
  1893.     #if (HAS_TMS99105A)
  1894.             case CPU_TMS99105A:
  1895.     #endif
  1896.     #if (HAS_TMS99110A)
  1897.             case CPU_TMS99110A:
  1898.     #endif
  1899.                 LOG(("Please use the new interrupt scheme for your new developments !\n"));
  1900.                 irq_line = 0;
  1901.                 break;
  1902. #endif
  1903. #if (HAS_Z8000)
  1904.             case CPU_Z8000:
  1905.                 switch (num)
  1906.                 {
  1907.                 case Z8000_NVI:         irq_line = 0; LOG(("Z8000 NVI\n")); break;
  1908.                 case Z8000_VI:            irq_line = 1; LOG(("Z8000 VI\n")); break;
  1909.                 default:                irq_line = 0; LOG(("Z8000 unknown\n"));
  1910.                 }
  1911.                 break;
  1912. #endif
  1913. #if (HAS_TMS320C10)
  1914.             case CPU_TMS320C10:
  1915.                 switch (num)
  1916.                 {
  1917.                 case TMS320C10_ACTIVE_INT:    irq_line = 0; LOG(("TMS32010 INT\n")); break;
  1918.                 case TMS320C10_ACTIVE_BIO:    irq_line = 1; LOG(("TMS32010 BIO\n")); break;
  1919.                 default:                    irq_line = 0; LOG(("TMS32010 unknown\n"));
  1920.                 }
  1921.                 break;
  1922. #endif
  1923. #if (HAS_ADSP2100)
  1924.             case CPU_ADSP2100:
  1925.                 switch (num)
  1926.                 {
  1927.                 case ADSP2100_IRQ0:         irq_line = 0; LOG(("ADSP2100 IRQ0\n")); break;
  1928.                 case ADSP2100_IRQ1:         irq_line = 1; LOG(("ADSP2100 IRQ1\n")); break;
  1929.                 case ADSP2100_IRQ2:         irq_line = 2; LOG(("ADSP2100 IRQ1\n")); break;
  1930.                 case ADSP2100_IRQ3:         irq_line = 3; LOG(("ADSP2100 IRQ1\n")); break;
  1931.                 default:                    irq_line = 0; LOG(("ADSP2100 unknown\n"));
  1932.                 }
  1933.                 break;
  1934. #endif
  1935.             default:
  1936.                 irq_line = 0;
  1937.                 /* else it should be an IRQ type; assume line 0 and store vector */
  1938.                 LOG(("unknown IRQ\n"));
  1939.             }
  1940.             cpu_irq_line_vector_w(cpunum, irq_line, num);
  1941.             cpu_manualirqcallback(irq_line | (cpunum << 3) | (HOLD_LINE << 6) );
  1942.         }
  1943.     }
  1944.  
  1945.     /* update the CPU's context */
  1946.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  1947.     activecpu = oldactive;
  1948.     if (activecpu >= 0) memorycontextswap(activecpu);
  1949.  
  1950.     /* trigger already generated by cpu_manualirqcallback or cpu_manualnmicallback */
  1951. }
  1952.  
  1953. static void cpu_clear_interrupts(int cpunum)
  1954. {
  1955.     int oldactive = activecpu;
  1956.     int i;
  1957.  
  1958.     /* swap to the CPU's context */
  1959.     activecpu = cpunum;
  1960.     memorycontextswap(activecpu);
  1961.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  1962.  
  1963.     /* clear NMI line */
  1964.     SETNMILINE(activecpu,CLEAR_LINE);
  1965.  
  1966.     /* clear all IRQ lines */
  1967.     for (i = 0; i < cpu[activecpu].intf->num_irqs; i++)
  1968.         SETIRQLINE(activecpu,i,CLEAR_LINE);
  1969.  
  1970.     /* update the CPU's context */
  1971.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  1972.     activecpu = oldactive;
  1973.     if (activecpu >= 0) memorycontextswap(activecpu);
  1974. }
  1975.  
  1976.  
  1977. static void cpu_reset_cpu(int cpunum)
  1978. {
  1979.     int oldactive = activecpu;
  1980.  
  1981.     /* swap to the CPU's context */
  1982.     activecpu = cpunum;
  1983.     memorycontextswap(activecpu);
  1984.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  1985.  
  1986.     /* reset the CPU */
  1987.     RESET(cpunum);
  1988.  
  1989.     /* Set the irq callback for the cpu */
  1990.     SETIRQCALLBACK(cpunum,cpu_irq_callbacks[cpunum]);
  1991.  
  1992.     /* update the CPU's context */
  1993.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  1994.     activecpu = oldactive;
  1995.     if (activecpu >= 0) memorycontextswap(activecpu);
  1996. }
  1997.  
  1998. /***************************************************************************
  1999.  
  2000.   Interrupt callback. This is called once per CPU interrupt by either the
  2001.   VBLANK handler or by the CPU's own timer directly, depending on whether
  2002.   or not the CPU's interrupts are synced to VBLANK.
  2003.  
  2004. ***************************************************************************/
  2005. static void cpu_vblankintcallback(int param)
  2006. {
  2007.     if (Machine->drv->cpu[param].vblank_interrupt)
  2008.         cpu_generate_interrupt(param, Machine->drv->cpu[param].vblank_interrupt, 0);
  2009.  
  2010.     /* update the counters */
  2011.     cpu[param].iloops--;
  2012. }
  2013.  
  2014.  
  2015. static void cpu_timedintcallback(int param)
  2016. {
  2017.     /* bail if there is no routine */
  2018.     if (!Machine->drv->cpu[param].timed_interrupt)
  2019.         return;
  2020.  
  2021.     /* generate the interrupt */
  2022.     cpu_generate_interrupt(param, Machine->drv->cpu[param].timed_interrupt, 0);
  2023. }
  2024.  
  2025.  
  2026. static void cpu_manualintcallback(int param)
  2027. {
  2028.     int intnum = param >> 3;
  2029.     int cpunum = param & 7;
  2030.  
  2031.     /* generate the interrupt */
  2032.     cpu_generate_interrupt(cpunum, 0, intnum);
  2033. }
  2034.  
  2035.  
  2036. static void cpu_clearintcallback(int param)
  2037. {
  2038.     /* clear the interrupts */
  2039.     cpu_clear_interrupts(param);
  2040. }
  2041.  
  2042.  
  2043. static void cpu_resetcallback(int param)
  2044. {
  2045.     int state = param >> 3;
  2046.     int cpunum = param & 7;
  2047.  
  2048.     /* reset the CPU */
  2049.     if (state == PULSE_LINE)
  2050.         cpu_reset_cpu(cpunum);
  2051.     else if (state == ASSERT_LINE)
  2052.     {
  2053. /* ASG - do we need this?        cpu_reset_cpu(cpunum);*/
  2054.         timer_suspendcpu(cpunum, 1, SUSPEND_REASON_RESET);    /* halt cpu */
  2055.     }
  2056.     else if (state == CLEAR_LINE)
  2057.     {
  2058.         if (timer_iscpususpended(cpunum, SUSPEND_REASON_RESET))
  2059.             cpu_reset_cpu(cpunum);
  2060.         timer_suspendcpu(cpunum, 0, SUSPEND_REASON_RESET);    /* restart cpu */
  2061.     }
  2062. }
  2063.  
  2064.  
  2065. static void cpu_haltcallback(int param)
  2066. {
  2067.     int state = param >> 3;
  2068.     int cpunum = param & 7;
  2069.  
  2070.     /* reset the CPU */
  2071.     if (state == ASSERT_LINE)
  2072.         timer_suspendcpu(cpunum, 1, SUSPEND_REASON_HALT);    /* halt cpu */
  2073.     else if (state == CLEAR_LINE)
  2074.         timer_suspendcpu(cpunum, 0, SUSPEND_REASON_HALT);    /* restart cpu */
  2075. }
  2076.  
  2077.  
  2078.  
  2079. /***************************************************************************
  2080.  
  2081.   VBLANK reset. Called at the start of emulation and once per VBLANK in
  2082.   order to update the input ports and reset the interrupt counter.
  2083.  
  2084. ***************************************************************************/
  2085. static void cpu_vblankreset(void)
  2086. {
  2087.     int i;
  2088.  
  2089.     /* read hi scores from disk */
  2090.     hs_update();
  2091.  
  2092.     /* read keyboard & update the status of the input ports */
  2093.     update_input_ports();
  2094.  
  2095.     /* reset the cycle counters */
  2096.     for (i = 0; i < totalcpu; i++)
  2097.     {
  2098.         if (!timer_iscpususpended(i, SUSPEND_ANY_REASON))
  2099.             cpu[i].iloops = Machine->drv->cpu[i].vblank_interrupts_per_frame - 1;
  2100.         else
  2101.             cpu[i].iloops = -1;
  2102.     }
  2103. }
  2104.  
  2105.  
  2106. /***************************************************************************
  2107.  
  2108.   VBLANK callback. This is called 'vblank_multipler' times per frame to
  2109.   service VBLANK-synced interrupts and to begin the screen update process.
  2110.  
  2111. ***************************************************************************/
  2112. static void cpu_firstvblankcallback(int param)
  2113. {
  2114.     /* now that we're synced up, pulse from here on out */
  2115.     vblank_timer = timer_pulse(vblank_period, param, cpu_vblankcallback);
  2116.  
  2117.     /* but we need to call the standard routine as well */
  2118.     cpu_vblankcallback(param);
  2119. }
  2120.  
  2121. /* note that calling this with param == -1 means count everything, but call no subroutines */
  2122. static void cpu_vblankcallback(int param)
  2123. {
  2124.     int i;
  2125.  
  2126.     /* loop over CPUs */
  2127.     for (i = 0; i < totalcpu; i++)
  2128.     {
  2129.         /* if the interrupt multiplier is valid */
  2130.         if (cpu[i].vblankint_multiplier != -1)
  2131.         {
  2132.             /* decrement; if we hit zero, generate the interrupt and reset the countdown */
  2133.             if (!--cpu[i].vblankint_countdown)
  2134.             {
  2135.                 if (param != -1)
  2136.                     cpu_vblankintcallback(i);
  2137.                 cpu[i].vblankint_countdown = cpu[i].vblankint_multiplier;
  2138.                 timer_reset(cpu[i].vblankint_timer, TIME_NEVER);
  2139.             }
  2140.         }
  2141.  
  2142.         /* else reset the VBLANK timer if this is going to be a real VBLANK */
  2143.         else if (vblank_countdown == 1)
  2144.             timer_reset(cpu[i].vblankint_timer, TIME_NEVER);
  2145.     }
  2146.  
  2147.     /* is it a real VBLANK? */
  2148.     if (!--vblank_countdown)
  2149.     {
  2150.         /* do we update the screen now? */
  2151.         if (!(Machine->drv->video_attributes & VIDEO_UPDATE_AFTER_VBLANK))
  2152.             usres = updatescreen();
  2153.  
  2154.         /* Set the timer to update the screen */
  2155.         timer_set(TIME_IN_USEC(Machine->drv->vblank_duration), 0, cpu_updatecallback);
  2156.         vblank = 1;
  2157.  
  2158.         /* reset the globals */
  2159.         cpu_vblankreset();
  2160.  
  2161.         /* reset the counter */
  2162.         vblank_countdown = vblank_multiplier;
  2163.     }
  2164. }
  2165.  
  2166.  
  2167. /***************************************************************************
  2168.  
  2169.   Video update callback. This is called a game-dependent amount of time
  2170.   after the VBLANK in order to trigger a video update.
  2171.  
  2172. ***************************************************************************/
  2173. static void cpu_updatecallback(int param)
  2174. {
  2175.     /* update the screen if we didn't before */
  2176.     if (Machine->drv->video_attributes & VIDEO_UPDATE_AFTER_VBLANK)
  2177.         usres = updatescreen();
  2178.     vblank = 0;
  2179.  
  2180.     /* update IPT_VBLANK input ports */
  2181.     inputport_vblank_end();
  2182.  
  2183.     /* check the watchdog */
  2184.     if (watchdog_counter > 0)
  2185.     {
  2186.         if (--watchdog_counter == 0)
  2187.         {
  2188. logerror("reset caused by the watchdog\n");
  2189.             machine_reset();
  2190.         }
  2191.     }
  2192.  
  2193.     current_frame++;
  2194.  
  2195.     /* reset the refresh timer */
  2196.     timer_reset(refresh_timer, TIME_NEVER);
  2197. }
  2198.  
  2199.  
  2200. /***************************************************************************
  2201.  
  2202.   Converts an integral timing rate into a period. Rates can be specified
  2203.   as follows:
  2204.  
  2205.         rate > 0       -> 'rate' cycles per frame
  2206.         rate == 0       -> 0
  2207.         rate >= -10000 -> 'rate' cycles per second
  2208.         rate < -10000  -> 'rate' nanoseconds
  2209.  
  2210. ***************************************************************************/
  2211. static double cpu_computerate(int value)
  2212. {
  2213.     /* values equal to zero are zero */
  2214.     if (value <= 0)
  2215.         return 0.0;
  2216.  
  2217.     /* values above between 0 and 50000 are in Hz */
  2218.     if (value < 50000)
  2219.         return TIME_IN_HZ(value);
  2220.  
  2221.     /* values greater than 50000 are in nanoseconds */
  2222.     else
  2223.         return TIME_IN_NSEC(value);
  2224. }
  2225.  
  2226.  
  2227. static void cpu_timeslicecallback(int param)
  2228. {
  2229.     timer_trigger(TRIGGER_TIMESLICE);
  2230. }
  2231.  
  2232.  
  2233. /***************************************************************************
  2234.  
  2235.   Initializes all the timers used by the CPU system.
  2236.  
  2237. ***************************************************************************/
  2238. static void cpu_inittimers(void)
  2239. {
  2240.     double first_time;
  2241.     int i, max, ipf;
  2242.  
  2243.     /* remove old timers */
  2244.     if (timeslice_timer)
  2245.         timer_remove(timeslice_timer);
  2246.     if (refresh_timer)
  2247.         timer_remove(refresh_timer);
  2248.     if (vblank_timer)
  2249.         timer_remove(vblank_timer);
  2250.  
  2251.     /* allocate a dummy timer at the minimum frequency to break things up */
  2252.     ipf = Machine->drv->cpu_slices_per_frame;
  2253.     if (ipf <= 0)
  2254.         ipf = 1;
  2255.     timeslice_period = TIME_IN_HZ(Machine->drv->frames_per_second * ipf);
  2256.     timeslice_timer = timer_pulse(timeslice_period, 0, cpu_timeslicecallback);
  2257.  
  2258.     /* allocate an infinite timer to track elapsed time since the last refresh */
  2259.     refresh_period = TIME_IN_HZ(Machine->drv->frames_per_second);
  2260.     refresh_period_inv = 1.0 / refresh_period;
  2261.     refresh_timer = timer_set(TIME_NEVER, 0, NULL);
  2262.  
  2263.     /* while we're at it, compute the scanline times */
  2264.     if (Machine->drv->vblank_duration)
  2265.         scanline_period = (refresh_period - TIME_IN_USEC(Machine->drv->vblank_duration)) /
  2266.                 (double)(Machine->drv->visible_area.max_y - Machine->drv->visible_area.min_y + 1);
  2267.     else
  2268.         scanline_period = refresh_period / (double)Machine->drv->screen_height;
  2269.     scanline_period_inv = 1.0 / scanline_period;
  2270.  
  2271.     /*
  2272.      *        The following code finds all the CPUs that are interrupting in sync with the VBLANK
  2273.      *        and sets up the VBLANK timer to run at the minimum number of cycles per frame in
  2274.      *        order to service all the synced interrupts
  2275.      */
  2276.  
  2277.     /* find the CPU with the maximum interrupts per frame */
  2278.     max = 1;
  2279.     for (i = 0; i < totalcpu; i++)
  2280.     {
  2281.         ipf = Machine->drv->cpu[i].vblank_interrupts_per_frame;
  2282.         if (ipf > max)
  2283.             max = ipf;
  2284.     }
  2285.  
  2286.     /* now find the LCD with the rest of the CPUs (brute force - these numbers aren't huge) */
  2287.     vblank_multiplier = max;
  2288.     while (1)
  2289.     {
  2290.         for (i = 0; i < totalcpu; i++)
  2291.         {
  2292.             ipf = Machine->drv->cpu[i].vblank_interrupts_per_frame;
  2293.             if (ipf > 0 && (vblank_multiplier % ipf) != 0)
  2294.                 break;
  2295.         }
  2296.         if (i == totalcpu)
  2297.             break;
  2298.         vblank_multiplier += max;
  2299.     }
  2300.  
  2301.     /* initialize the countdown timers and intervals */
  2302.     for (i = 0; i < totalcpu; i++)
  2303.     {
  2304.         ipf = Machine->drv->cpu[i].vblank_interrupts_per_frame;
  2305.         if (ipf > 0)
  2306.             cpu[i].vblankint_countdown = cpu[i].vblankint_multiplier = vblank_multiplier / ipf;
  2307.         else
  2308.             cpu[i].vblankint_countdown = cpu[i].vblankint_multiplier = -1;
  2309.     }
  2310.  
  2311.     /* allocate a vblank timer at the frame rate * the LCD number of interrupts per frame */
  2312.     vblank_period = TIME_IN_HZ(Machine->drv->frames_per_second * vblank_multiplier);
  2313.     vblank_timer = timer_pulse(vblank_period, 0, cpu_vblankcallback);
  2314.     vblank_countdown = vblank_multiplier;
  2315.  
  2316.     /*
  2317.      *        The following code creates individual timers for each CPU whose interrupts are not
  2318.      *        synced to the VBLANK, and computes the typical number of cycles per interrupt
  2319.      */
  2320.  
  2321.     /* start the CPU interrupt timers */
  2322.     for (i = 0; i < totalcpu; i++)
  2323.     {
  2324.         ipf = Machine->drv->cpu[i].vblank_interrupts_per_frame;
  2325.  
  2326.         /* remove old timers */
  2327.         if (cpu[i].vblankint_timer)
  2328.             timer_remove(cpu[i].vblankint_timer);
  2329.         if (cpu[i].timedint_timer)
  2330.             timer_remove(cpu[i].timedint_timer);
  2331.  
  2332.         /* compute the average number of cycles per interrupt */
  2333.         if (ipf <= 0)
  2334.             ipf = 1;
  2335.         cpu[i].vblankint_period = TIME_IN_HZ(Machine->drv->frames_per_second * ipf);
  2336.         cpu[i].vblankint_timer = timer_set(TIME_NEVER, 0, NULL);
  2337.  
  2338.         /* see if we need to allocate a CPU timer */
  2339.         ipf = Machine->drv->cpu[i].timed_interrupts_per_second;
  2340.         if (ipf)
  2341.         {
  2342.             cpu[i].timedint_period = cpu_computerate(ipf);
  2343.             cpu[i].timedint_timer = timer_pulse(cpu[i].timedint_period, i, cpu_timedintcallback);
  2344.         }
  2345.     }
  2346.  
  2347.     /* note that since we start the first frame on the refresh, we can't pulse starting
  2348.        immediately; instead, we back up one VBLANK period, and inch forward until we hit
  2349.        positive time. That time will be the time of the first VBLANK timer callback */
  2350.     timer_remove(vblank_timer);
  2351.  
  2352.     first_time = -TIME_IN_USEC(Machine->drv->vblank_duration) + vblank_period;
  2353.     while (first_time < 0)
  2354.     {
  2355.         cpu_vblankcallback(-1);
  2356.         first_time += vblank_period;
  2357.     }
  2358.     vblank_timer = timer_set(first_time, 0, cpu_firstvblankcallback);
  2359. }
  2360.  
  2361.  
  2362. /* AJP 981016 */
  2363. int cpu_is_saving_context(int _activecpu)
  2364. {
  2365.     return (cpu[_activecpu].save_context);
  2366. }
  2367.  
  2368.  
  2369. /* JB 971019 */
  2370. void* cpu_getcontext(int _activecpu)
  2371. {
  2372.     return cpu[_activecpu].context;
  2373. }
  2374.  
  2375.  
  2376. /***************************************************************************
  2377.   Retrieve or set the entire context of the active CPU
  2378. ***************************************************************************/
  2379.  
  2380. unsigned cpu_get_context(void *context)
  2381. {
  2382.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2383.     return GETCONTEXT(cpunum,context);
  2384. }
  2385.  
  2386. void cpu_set_context(void *context)
  2387. {
  2388.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2389.     SETCONTEXT(cpunum,context);
  2390. }
  2391.  
  2392. /***************************************************************************
  2393.   Retrieve or set the value of a specific register of the active CPU
  2394. ***************************************************************************/
  2395.  
  2396. unsigned cpu_get_reg(int regnum)
  2397. {
  2398.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2399.     return GETREG(cpunum,regnum);
  2400. }
  2401.  
  2402. void cpu_set_reg(int regnum, unsigned val)
  2403. {
  2404.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2405.     SETREG(cpunum,regnum,val);
  2406. }
  2407.  
  2408. /***************************************************************************
  2409.  
  2410.   Get various CPU information
  2411.  
  2412. ***************************************************************************/
  2413.  
  2414. /***************************************************************************
  2415.   Returns the number of address bits for the active CPU
  2416. ***************************************************************************/
  2417. unsigned cpu_address_bits(void)
  2418. {
  2419.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2420.     return cpuintf[CPU_TYPE(cpunum)].address_bits;
  2421. }
  2422.  
  2423. /***************************************************************************
  2424.   Returns the address bit mask for the active CPU
  2425. ***************************************************************************/
  2426. unsigned cpu_address_mask(void)
  2427. {
  2428.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2429.     return (1 << cpuintf[CPU_TYPE(cpunum)].address_bits) - 1;
  2430. }
  2431.  
  2432. /***************************************************************************
  2433.   Returns the address shift factor for the active CPU
  2434. ***************************************************************************/
  2435. int cpu_address_shift(void)
  2436. {
  2437.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2438.     return cpuintf[CPU_TYPE(cpunum)].address_shift;
  2439. }
  2440.  
  2441. /***************************************************************************
  2442.   Returns the endianess for the active CPU
  2443. ***************************************************************************/
  2444. unsigned cpu_endianess(void)
  2445. {
  2446.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2447.     return cpuintf[CPU_TYPE(cpunum)].endianess;
  2448. }
  2449.  
  2450. /***************************************************************************
  2451.   Returns the code align unit for the active CPU (1 byte, 2 word, ...)
  2452. ***************************************************************************/
  2453. unsigned cpu_align_unit(void)
  2454. {
  2455.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2456.     return cpuintf[CPU_TYPE(cpunum)].align_unit;
  2457. }
  2458.  
  2459. /***************************************************************************
  2460.   Returns the max. instruction length for the active CPU
  2461. ***************************************************************************/
  2462. unsigned cpu_max_inst_len(void)
  2463. {
  2464.     int cpunum = (activecpu < 0) ? 0 : activecpu;
  2465.     return cpuintf[CPU_TYPE(cpunum)].max_inst_len;
  2466. }
  2467.  
  2468. /***************************************************************************
  2469.   Returns the name for the active CPU
  2470. ***************************************************************************/
  2471. const char *cpu_name(void)
  2472. {
  2473.     if( activecpu >= 0 )
  2474.         return CPUINFO(activecpu,NULL,CPU_INFO_NAME);
  2475.     return "";
  2476. }
  2477.  
  2478. /***************************************************************************
  2479.   Returns the family name for the active CPU
  2480. ***************************************************************************/
  2481. const char *cpu_core_family(void)
  2482. {
  2483.     if( activecpu >= 0 )
  2484.         return CPUINFO(activecpu,NULL,CPU_INFO_FAMILY);
  2485.     return "";
  2486. }
  2487.  
  2488. /***************************************************************************
  2489.   Returns the version number for the active CPU
  2490. ***************************************************************************/
  2491. const char *cpu_core_version(void)
  2492. {
  2493.     if( activecpu >= 0 )
  2494.         return CPUINFO(activecpu,NULL,CPU_INFO_VERSION);
  2495.     return "";
  2496. }
  2497.  
  2498. /***************************************************************************
  2499.   Returns the core filename for the active CPU
  2500. ***************************************************************************/
  2501. const char *cpu_core_file(void)
  2502. {
  2503.     if( activecpu >= 0 )
  2504.         return CPUINFO(activecpu,NULL,CPU_INFO_FILE);
  2505.     return "";
  2506. }
  2507.  
  2508. /***************************************************************************
  2509.   Returns the credits for the active CPU
  2510. ***************************************************************************/
  2511. const char *cpu_core_credits(void)
  2512. {
  2513.     if( activecpu >= 0 )
  2514.         return CPUINFO(activecpu,NULL,CPU_INFO_CREDITS);
  2515.     return "";
  2516. }
  2517.  
  2518. /***************************************************************************
  2519.   Returns the register layout for the active CPU (debugger)
  2520. ***************************************************************************/
  2521. const char *cpu_reg_layout(void)
  2522. {
  2523.     if( activecpu >= 0 )
  2524.         return CPUINFO(activecpu,NULL,CPU_INFO_REG_LAYOUT);
  2525.     return "";
  2526. }
  2527.  
  2528. /***************************************************************************
  2529.   Returns the window layout for the active CPU (debugger)
  2530. ***************************************************************************/
  2531. const char *cpu_win_layout(void)
  2532. {
  2533.     if( activecpu >= 0 )
  2534.         return CPUINFO(activecpu,NULL,CPU_INFO_WIN_LAYOUT);
  2535.     return "";
  2536. }
  2537.  
  2538. /***************************************************************************
  2539.   Returns a dissassembled instruction for the active CPU
  2540. ***************************************************************************/
  2541. unsigned cpu_dasm(char *buffer, unsigned pc)
  2542. {
  2543.     if( activecpu >= 0 )
  2544.         return CPUDASM(activecpu,buffer,pc);
  2545.     return 0;
  2546. }
  2547.  
  2548. /***************************************************************************
  2549.   Returns a flags (state, condition codes) string for the active CPU
  2550. ***************************************************************************/
  2551. const char *cpu_flags(void)
  2552. {
  2553.     if( activecpu >= 0 )
  2554.         return CPUINFO(activecpu,NULL,CPU_INFO_FLAGS);
  2555.     return "";
  2556. }
  2557.  
  2558. /***************************************************************************
  2559.   Returns a specific register string for the currently active CPU
  2560. ***************************************************************************/
  2561. const char *cpu_dump_reg(int regnum)
  2562. {
  2563.     if( activecpu >= 0 )
  2564.         return CPUINFO(activecpu,NULL,CPU_INFO_REG+regnum);
  2565.     return "";
  2566. }
  2567.  
  2568. /***************************************************************************
  2569.   Returns a state dump for the currently active CPU
  2570. ***************************************************************************/
  2571. const char *cpu_dump_state(void)
  2572. {
  2573.     static char buffer[1024+1];
  2574.     unsigned addr_width = (cpu_address_bits() + 3) / 4;
  2575.     char *dst = buffer;
  2576.     const char *src;
  2577.     const INT8 *regs;
  2578.     int width;
  2579.  
  2580.     dst += sprintf(dst, "CPU #%d [%s]\n", activecpu, cputype_name(CPU_TYPE(activecpu)));
  2581.     width = 0;
  2582.     regs = (INT8 *)cpu_reg_layout();
  2583.     while( *regs )
  2584.     {
  2585.         if( *regs == -1 )
  2586.         {
  2587.             dst += sprintf(dst, "\n");
  2588.             width = 0;
  2589.         }
  2590.         else
  2591.         {
  2592.             src = cpu_dump_reg( *regs );
  2593.             if( *src )
  2594.             {
  2595.                 if( width + strlen(src) + 1 >= 80 )
  2596.                 {
  2597.                     dst += sprintf(dst, "\n");
  2598.                     width = 0;
  2599.                 }
  2600.                 dst += sprintf(dst, "%s ", src);
  2601.                 width += strlen(src) + 1;
  2602.             }
  2603.         }
  2604.         regs++;
  2605.     }
  2606.     dst += sprintf(dst, "\n%0*X: ", addr_width, cpu_get_pc());
  2607.     cpu_dasm( dst, cpu_get_pc() );
  2608.     strcat(dst, "\n\n");
  2609.  
  2610.     return buffer;
  2611. }
  2612.  
  2613. /***************************************************************************
  2614.   Returns the number of address bits for a specific CPU type
  2615. ***************************************************************************/
  2616. unsigned cputype_address_bits(int cpu_type)
  2617. {
  2618.     cpu_type &= ~CPU_FLAGS_MASK;
  2619.     if( cpu_type < CPU_COUNT )
  2620.         return cpuintf[cpu_type].address_bits;
  2621.     return 0;
  2622. }
  2623.  
  2624. /***************************************************************************
  2625.   Returns the address bit mask for a specific CPU type
  2626. ***************************************************************************/
  2627. unsigned cputype_address_mask(int cpu_type)
  2628. {
  2629.     cpu_type &= ~CPU_FLAGS_MASK;
  2630.     if( cpu_type < CPU_COUNT )
  2631.         return (1 << cpuintf[cpu_type].address_bits) - 1;
  2632.     return 0;
  2633. }
  2634.  
  2635. /***************************************************************************
  2636.   Returns the address shift factor for a specific CPU type
  2637. ***************************************************************************/
  2638. int cputype_address_shift(int cpu_type)
  2639. {
  2640.     cpu_type &= ~CPU_FLAGS_MASK;
  2641.     if( cpu_type < CPU_COUNT )
  2642.         return cpuintf[cpu_type].address_shift;
  2643.     return 0;
  2644. }
  2645.  
  2646. /***************************************************************************
  2647.   Returns the endianess for a specific CPU type
  2648. ***************************************************************************/
  2649. unsigned cputype_endianess(int cpu_type)
  2650. {
  2651.     cpu_type &= ~CPU_FLAGS_MASK;
  2652.     if( cpu_type < CPU_COUNT )
  2653.         return cpuintf[cpu_type].endianess;
  2654.     return 0;
  2655. }
  2656.  
  2657. /***************************************************************************
  2658.   Returns the code align unit for a speciific CPU type (1 byte, 2 word, ...)
  2659. ***************************************************************************/
  2660. unsigned cputype_align_unit(int cpu_type)
  2661. {
  2662.     cpu_type &= ~CPU_FLAGS_MASK;
  2663.     if( cpu_type < CPU_COUNT )
  2664.         return cpuintf[cpu_type].align_unit;
  2665.     return 0;
  2666. }
  2667.  
  2668. /***************************************************************************
  2669.   Returns the max. instruction length for a specific CPU type
  2670. ***************************************************************************/
  2671. unsigned cputype_max_inst_len(int cpu_type)
  2672. {
  2673.     cpu_type &= ~CPU_FLAGS_MASK;
  2674.     if( cpu_type < CPU_COUNT )
  2675.         return cpuintf[cpu_type].max_inst_len;
  2676.     return 0;
  2677. }
  2678.  
  2679. /***************************************************************************
  2680.   Returns the name for a specific CPU type
  2681. ***************************************************************************/
  2682. const char *cputype_name(int cpu_type)
  2683. {
  2684.     cpu_type &= ~CPU_FLAGS_MASK;
  2685.     if( cpu_type < CPU_COUNT )
  2686.         return IFC_INFO(cpu_type,NULL,CPU_INFO_NAME);
  2687.     return "";
  2688. }
  2689.  
  2690. /***************************************************************************
  2691.   Returns the family name for a specific CPU type
  2692. ***************************************************************************/
  2693. const char *cputype_core_family(int cpu_type)
  2694. {
  2695.     cpu_type &= ~CPU_FLAGS_MASK;
  2696.     if( cpu_type < CPU_COUNT )
  2697.         return IFC_INFO(cpu_type,NULL,CPU_INFO_FAMILY);
  2698.     return "";
  2699. }
  2700.  
  2701. /***************************************************************************
  2702.   Returns the version number for a specific CPU type
  2703. ***************************************************************************/
  2704. const char *cputype_core_version(int cpu_type)
  2705. {
  2706.     cpu_type &= ~CPU_FLAGS_MASK;
  2707.     if( cpu_type < CPU_COUNT )
  2708.         return IFC_INFO(cpu_type,NULL,CPU_INFO_VERSION);
  2709.     return "";
  2710. }
  2711.  
  2712. /***************************************************************************
  2713.   Returns the core filename for a specific CPU type
  2714. ***************************************************************************/
  2715. const char *cputype_core_file(int cpu_type)
  2716. {
  2717.     cpu_type &= ~CPU_FLAGS_MASK;
  2718.     if( cpu_type < CPU_COUNT )
  2719.         return IFC_INFO(cpu_type,NULL,CPU_INFO_FILE);
  2720.     return "";
  2721. }
  2722.  
  2723. /***************************************************************************
  2724.   Returns the credits for a specific CPU type
  2725. ***************************************************************************/
  2726. const char *cputype_core_credits(int cpu_type)
  2727. {
  2728.     cpu_type &= ~CPU_FLAGS_MASK;
  2729.     if( cpu_type < CPU_COUNT )
  2730.         return IFC_INFO(cpu_type,NULL,CPU_INFO_CREDITS);
  2731.     return "";
  2732. }
  2733.  
  2734. /***************************************************************************
  2735.   Returns the register layout for a specific CPU type (debugger)
  2736. ***************************************************************************/
  2737. const char *cputype_reg_layout(int cpu_type)
  2738. {
  2739.     cpu_type &= ~CPU_FLAGS_MASK;
  2740.     if( cpu_type < CPU_COUNT )
  2741.         return IFC_INFO(cpu_type,NULL,CPU_INFO_REG_LAYOUT);
  2742.     return "";
  2743. }
  2744.  
  2745. /***************************************************************************
  2746.   Returns the window layout for a specific CPU type (debugger)
  2747. ***************************************************************************/
  2748. const char *cputype_win_layout(int cpu_type)
  2749. {
  2750.     cpu_type &= ~CPU_FLAGS_MASK;
  2751.     if( cpu_type < CPU_COUNT )
  2752.         return IFC_INFO(cpu_type,NULL,CPU_INFO_WIN_LAYOUT);
  2753.  
  2754.     /* just in case... */
  2755.     return (const char *)default_win_layout;
  2756. }
  2757.  
  2758. /***************************************************************************
  2759.   Returns the number of address bits for a specific CPU number
  2760. ***************************************************************************/
  2761. unsigned cpunum_address_bits(int cpunum)
  2762. {
  2763.     if( cpunum < totalcpu )
  2764.         return cputype_address_bits(CPU_TYPE(cpunum));
  2765.     return 0;
  2766. }
  2767.  
  2768. /***************************************************************************
  2769.   Returns the address bit mask for a specific CPU number
  2770. ***************************************************************************/
  2771. unsigned cpunum_address_mask(int cpunum)
  2772. {
  2773.     if( cpunum < totalcpu )
  2774.         return cputype_address_mask(CPU_TYPE(cpunum));
  2775.     return 0;
  2776. }
  2777.  
  2778. /***************************************************************************
  2779.   Returns the endianess for a specific CPU number
  2780. ***************************************************************************/
  2781. unsigned cpunum_endianess(int cpunum)
  2782. {
  2783.     if( cpunum < totalcpu )
  2784.         return cputype_endianess(CPU_TYPE(cpunum));
  2785.     return 0;
  2786. }
  2787.  
  2788. /***************************************************************************
  2789.   Returns the code align unit for the active CPU (1 byte, 2 word, ...)
  2790. ***************************************************************************/
  2791. unsigned cpunum_align_unit(int cpunum)
  2792. {
  2793.     if( cpunum < totalcpu )
  2794.         return cputype_align_unit(CPU_TYPE(cpunum));
  2795.     return 0;
  2796. }
  2797.  
  2798. /***************************************************************************
  2799.   Returns the max. instruction length for a specific CPU number
  2800. ***************************************************************************/
  2801. unsigned cpunum_max_inst_len(int cpunum)
  2802. {
  2803.     if( cpunum < totalcpu )
  2804.         return cputype_max_inst_len(CPU_TYPE(cpunum));
  2805.     return 0;
  2806. }
  2807.  
  2808. /***************************************************************************
  2809.   Returns the name for a specific CPU number
  2810. ***************************************************************************/
  2811. const char *cpunum_name(int cpunum)
  2812. {
  2813.     if( cpunum < totalcpu )
  2814.         return cputype_name(CPU_TYPE(cpunum));
  2815.     return "";
  2816. }
  2817.  
  2818. /***************************************************************************
  2819.   Returns the family name for a specific CPU number
  2820. ***************************************************************************/
  2821. const char *cpunum_core_family(int cpunum)
  2822. {
  2823.     if( cpunum < totalcpu )
  2824.         return cputype_core_family(CPU_TYPE(cpunum));
  2825.     return "";
  2826. }
  2827.  
  2828. /***************************************************************************
  2829.   Returns the core version for a specific CPU number
  2830. ***************************************************************************/
  2831. const char *cpunum_core_version(int cpunum)
  2832. {
  2833.     if( cpunum < totalcpu )
  2834.         return cputype_core_version(CPU_TYPE(cpunum));
  2835.     return "";
  2836. }
  2837.  
  2838. /***************************************************************************
  2839.   Returns the core filename for a specific CPU number
  2840. ***************************************************************************/
  2841. const char *cpunum_core_file(int cpunum)
  2842. {
  2843.     if( cpunum < totalcpu )
  2844.         return cputype_core_file(CPU_TYPE(cpunum));
  2845.     return "";
  2846. }
  2847.  
  2848. /***************************************************************************
  2849.   Returns the credits for a specific CPU number
  2850. ***************************************************************************/
  2851. const char *cpunum_core_credits(int cpunum)
  2852. {
  2853.     if( cpunum < totalcpu )
  2854.         return cputype_core_credits(CPU_TYPE(cpunum));
  2855.     return "";
  2856. }
  2857.  
  2858. /***************************************************************************
  2859.   Returns (debugger) register layout for a specific CPU number
  2860. ***************************************************************************/
  2861. const char *cpunum_reg_layout(int cpunum)
  2862. {
  2863.     if( cpunum < totalcpu )
  2864.         return cputype_reg_layout(CPU_TYPE(cpunum));
  2865.     return "";
  2866. }
  2867.  
  2868. /***************************************************************************
  2869.   Returns (debugger) window layout for a specific CPU number
  2870. ***************************************************************************/
  2871. const char *cpunum_win_layout(int cpunum)
  2872. {
  2873.     if( cpunum < totalcpu )
  2874.         return cputype_win_layout(CPU_TYPE(cpunum));
  2875.     return (const char *)default_win_layout;
  2876. }
  2877.  
  2878. /***************************************************************************
  2879.   Return a register value for a specific CPU number of the running machine
  2880. ***************************************************************************/
  2881. unsigned cpunum_get_reg(int cpunum, int regnum)
  2882. {
  2883.     int oldactive;
  2884.     unsigned val = 0;
  2885.  
  2886.     if( cpunum == activecpu )
  2887.         return cpu_get_reg( regnum );
  2888.  
  2889.     /* swap to the CPU's context */
  2890.     if (activecpu >= 0)
  2891.         if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  2892.     oldactive = activecpu;
  2893.     activecpu = cpunum;
  2894.     memorycontextswap(activecpu);
  2895.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  2896.  
  2897.     val = GETREG(activecpu,regnum);
  2898.  
  2899.     /* update the CPU's context */
  2900.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  2901.     activecpu = oldactive;
  2902.     if (activecpu >= 0)
  2903.     {
  2904.         memorycontextswap(activecpu);
  2905.         if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  2906.     }
  2907.  
  2908.     return val;
  2909. }
  2910.  
  2911. /***************************************************************************
  2912.   Set a register value for a specific CPU number of the running machine
  2913. ***************************************************************************/
  2914. void cpunum_set_reg(int cpunum, int regnum, unsigned val)
  2915. {
  2916.     int oldactive;
  2917.  
  2918.     if( cpunum == activecpu )
  2919.     {
  2920.         cpu_set_reg( regnum, val );
  2921.         return;
  2922.     }
  2923.  
  2924.     /* swap to the CPU's context */
  2925.     if (activecpu >= 0)
  2926.         if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  2927.     oldactive = activecpu;
  2928.     activecpu = cpunum;
  2929.     memorycontextswap(activecpu);
  2930.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  2931.  
  2932.     SETREG(activecpu,regnum,val);
  2933.  
  2934.     /* update the CPU's context */
  2935.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  2936.     activecpu = oldactive;
  2937.     if (activecpu >= 0)
  2938.     {
  2939.         memorycontextswap(activecpu);
  2940.         if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  2941.     }
  2942. }
  2943.  
  2944. /***************************************************************************
  2945.   Return a dissassembled instruction for a specific CPU
  2946. ***************************************************************************/
  2947. unsigned cpunum_dasm(int cpunum,char *buffer,unsigned pc)
  2948. {
  2949.     unsigned result;
  2950.     int oldactive;
  2951.  
  2952.     if( cpunum == activecpu )
  2953.         return cpu_dasm(buffer,pc);
  2954.  
  2955.     /* swap to the CPU's context */
  2956.     if (activecpu >= 0)
  2957.         if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  2958.     oldactive = activecpu;
  2959.     activecpu = cpunum;
  2960.     memorycontextswap(activecpu);
  2961.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  2962.  
  2963.     result = CPUDASM(activecpu,buffer,pc);
  2964.  
  2965.     /* update the CPU's context */
  2966.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  2967.     activecpu = oldactive;
  2968.     if (activecpu >= 0)
  2969.     {
  2970.         memorycontextswap(activecpu);
  2971.         if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  2972.     }
  2973.  
  2974.     return result;
  2975. }
  2976.  
  2977. /***************************************************************************
  2978.   Return a flags (state, condition codes) string for a specific CPU
  2979. ***************************************************************************/
  2980. const char *cpunum_flags(int cpunum)
  2981. {
  2982.     const char *result;
  2983.     int oldactive;
  2984.  
  2985.     if( cpunum == activecpu )
  2986.         return cpu_flags();
  2987.  
  2988.     /* swap to the CPU's context */
  2989.     if (activecpu >= 0)
  2990.         if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  2991.     oldactive = activecpu;
  2992.     activecpu = cpunum;
  2993.     memorycontextswap(activecpu);
  2994.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  2995.  
  2996.     result = CPUINFO(activecpu,NULL,CPU_INFO_FLAGS);
  2997.  
  2998.     /* update the CPU's context */
  2999.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  3000.     activecpu = oldactive;
  3001.     if (activecpu >= 0)
  3002.     {
  3003.         memorycontextswap(activecpu);
  3004.         if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  3005.     }
  3006.  
  3007.     return result;
  3008. }
  3009.  
  3010. /***************************************************************************
  3011.   Return a specific register string for a specific CPU
  3012. ***************************************************************************/
  3013. const char *cpunum_dump_reg(int cpunum, int regnum)
  3014. {
  3015.     const char *result;
  3016.     int oldactive;
  3017.  
  3018.     if( cpunum == activecpu )
  3019.         return cpu_dump_reg(regnum);
  3020.  
  3021.     /* swap to the CPU's context */
  3022.     if (activecpu >= 0)
  3023.         if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  3024.     oldactive = activecpu;
  3025.     activecpu = cpunum;
  3026.     memorycontextswap(activecpu);
  3027.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  3028.  
  3029.     result = CPUINFO(activecpu,NULL,CPU_INFO_REG+regnum);
  3030.  
  3031.     /* update the CPU's context */
  3032.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  3033.     activecpu = oldactive;
  3034.     if (activecpu >= 0)
  3035.     {
  3036.         memorycontextswap(activecpu);
  3037.         if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  3038.     }
  3039.  
  3040.     return result;
  3041. }
  3042.  
  3043. /***************************************************************************
  3044.   Return a state dump for a specific CPU
  3045. ***************************************************************************/
  3046. const char *cpunum_dump_state(int cpunum)
  3047. {
  3048.     static char buffer[1024+1];
  3049.     int oldactive;
  3050.  
  3051.     /* swap to the CPU's context */
  3052.     if (activecpu >= 0)
  3053.         if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  3054.     oldactive = activecpu;
  3055.     activecpu = cpunum;
  3056.     memorycontextswap(activecpu);
  3057.     if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  3058.  
  3059.     strcpy( buffer, cpu_dump_state() );
  3060.  
  3061.     /* update the CPU's context */
  3062.     if (cpu[activecpu].save_context) GETCONTEXT(activecpu, cpu[activecpu].context);
  3063.     activecpu = oldactive;
  3064.     if (activecpu >= 0)
  3065.     {
  3066.         memorycontextswap(activecpu);
  3067.         if (cpu[activecpu].save_context) SETCONTEXT(activecpu, cpu[activecpu].context);
  3068.     }
  3069.  
  3070.     return buffer;
  3071. }
  3072.  
  3073. /***************************************************************************
  3074.   Dump all CPU's state to stdout
  3075. ***************************************************************************/
  3076. void cpu_dump_states(void)
  3077. {
  3078.     int i;
  3079.  
  3080.     for( i = 0; i < totalcpu; i++ )
  3081.     {
  3082.         puts( cpunum_dump_state(i) );
  3083.     }
  3084.     fflush(stdout);
  3085. }
  3086.  
  3087. /***************************************************************************
  3088.  
  3089.   Dummy interfaces for non-CPUs
  3090.  
  3091. ***************************************************************************/
  3092. static void Dummy_reset(void *param) { }
  3093. static void Dummy_exit(void) { }
  3094. static int Dummy_execute(int cycles) { return cycles; }
  3095. static void Dummy_burn(int cycles) { }
  3096. static unsigned Dummy_get_context(void *regs) { return 0; }
  3097. static void Dummy_set_context(void *regs) { }
  3098. static unsigned Dummy_get_pc(void) { return 0; }
  3099. static void Dummy_set_pc(unsigned val) { }
  3100. static unsigned Dummy_get_sp(void) { return 0; }
  3101. static void Dummy_set_sp(unsigned val) { }
  3102. static unsigned Dummy_get_reg(int regnum) { return 0; }
  3103. static void Dummy_set_reg(int regnum, unsigned val) { }
  3104. static void Dummy_set_nmi_line(int state) { }
  3105. static void Dummy_set_irq_line(int irqline, int state) { }
  3106. static void Dummy_set_irq_callback(int (*callback)(int irqline)) { }
  3107.  
  3108. /****************************************************************************
  3109.  * Return a formatted string for a register
  3110.  ****************************************************************************/
  3111. static const char *Dummy_info(void *context, int regnum)
  3112. {
  3113.     if( !context && regnum )
  3114.         return "";
  3115.  
  3116.     switch (regnum)
  3117.     {
  3118.         case CPU_INFO_NAME: return "Dummy";
  3119.         case CPU_INFO_FAMILY: return "no CPU";
  3120.         case CPU_INFO_VERSION: return "0.0";
  3121.         case CPU_INFO_FILE: return __FILE__;
  3122.         case CPU_INFO_CREDITS: return "The MAME team.";
  3123.     }
  3124.     return "";
  3125. }
  3126.  
  3127. static unsigned Dummy_dasm(char *buffer, unsigned pc)
  3128. {
  3129.     strcpy(buffer, "???");
  3130.     return 1;
  3131. }
  3132.  
  3133.